@@ -21,10 +21,12 @@ import (
21
21
"time"
22
22
)
23
23
24
- func WriteToStderr (args ... interface {}) {
24
+ func writeToStderr (args ... interface {}) {
25
+ safeStderr .Lock ()
25
26
if _ , err := fmt .Fprintln (os .Stderr , args ... ); err != nil {
26
27
fmt .Println ("adcca45f-8d7b-4d4a-8fd2-7683b7b375b5" , "could not write to stderr:" , err )
27
28
}
29
+ safeStderr .Unlock ()
28
30
}
29
31
30
32
var safeStdout = writer .NewSafeWriter (os .Stdout )
@@ -43,6 +45,7 @@ type Logger struct {
43
45
LockUuid string
44
46
EnvPrefix string
45
47
LogLevel shared.LogLevel
48
+ File * os.File
46
49
}
47
50
48
51
type LoggerParams struct {
@@ -56,10 +59,17 @@ type LoggerParams struct {
56
59
LockUuid string
57
60
EnvPrefix string
58
61
LogLevel shared.LogLevel
62
+ File * os.File
59
63
}
60
64
61
65
func NewLogger (p LoggerParams ) * Logger {
62
66
67
+ file := p .File
68
+
69
+ if file == nil {
70
+ file = os .Stdout
71
+ }
72
+
63
73
hostName := p .HostName
64
74
65
75
if hostName == "" {
@@ -87,7 +97,7 @@ func NewLogger(p LoggerParams) *Logger {
87
97
88
98
if os .Getenv ("jlog_log_json" ) == "yes" {
89
99
if p .ForceJSON {
90
- WriteToStderr ("forceJSON:true was used, but the 'jlog_log_json' env var was set to 'yes'." )
100
+ writeToStderr ("forceJSON:true was used, but the 'jlog_log_json' env var was set to 'yes'." )
91
101
}
92
102
isLoggingJson = true
93
103
}
@@ -128,6 +138,7 @@ func NewLogger(p LoggerParams) *Logger {
128
138
LockUuid : p .LockUuid ,
129
139
EnvPrefix : p .EnvPrefix ,
130
140
LogLevel : p .LogLevel ,
141
+ File : file ,
131
142
}
132
143
}
133
144
@@ -276,8 +287,23 @@ func (l *Logger) Create(m *map[string]interface{}) *Logger {
276
287
return l .Child (m )
277
288
}
278
289
279
- func (l * Logger ) writePretty (level shared.LogLevel , m * MetaFields , args * []interface {}) {
290
+ func (l * Logger ) writeToFile (level shared.LogLevel , m * MetaFields , args * []interface {}) {
291
+ b := l .getPrettyString (level , m , args )
292
+ l .File .WriteString (b .String ())
293
+ // _, err := io.Copy(l.File, b.) // TODO: copy to file, instead of buffering b.String()
294
+ }
295
+
296
+ type StrangBuilda struct {
297
+ strings.Builder
298
+ }
299
+
300
+ func (s StrangBuilda ) Read (b []byte ) (int , error ) {
301
+ return 0 , nil
302
+ }
303
+
304
+ func (l * Logger ) getPrettyString (level shared.LogLevel , m * MetaFields , args * []interface {}) * strings.Builder {
280
305
306
+ var b strings.Builder
281
307
date := time .Now ().UTC ().String ()[11 :25 ] // only first 25 chars
282
308
stylizedLevel := "<undefined>"
283
309
@@ -304,59 +330,13 @@ func (l *Logger) writePretty(level shared.LogLevel, m *MetaFields, args *[]inter
304
330
break
305
331
}
306
332
307
- buf := []string {
308
- aurora .Gray (9 , date ).String (), " " ,
309
- stylizedLevel , " " ,
310
- aurora .Gray (12 , "app:" ).String () + aurora .Italic (l .AppName ).String (), " " ,
311
- }
312
-
313
- shared .M1 .Lock ()
314
- peekItem , err := lockStack .Peek ()
315
-
316
- if err != nil && peekItem != nil {
317
- panic ("library error." )
318
- }
319
-
320
- var doUnlock = false
321
- if peekItem != nil {
322
-
323
- if peekItem .Id != l .LockUuid {
324
- //fmt.Println(fmt.Sprintf("%+v", lockStack))
325
- doUnlock = true
326
- shared .M1 .Unlock ()
327
- lockStack .Print ("789" )
328
- fmt .Println ("here 1" , peekItem .Id )
329
- peekItem .Lck .Lock ()
330
- fmt .Println ("here 2" )
331
- defer func () {
332
- peekItem .Lck .Unlock ()
333
- }()
334
- }
335
- //if peekItem.Id == l.LockUuid {
336
- // defer func() {
337
- // peekItem.Lck.Unlock()
338
- // lockStack.Pop()
339
- // }()
340
- //} else {
341
- // peekItem.Lck.Lock()
342
- // defer func() {
343
- // peekItem.Lck.Unlock()
344
- // }()
345
- //}
346
- }
347
-
348
- if ! doUnlock {
349
- shared .M1 .Unlock ()
350
- }
351
-
352
- defer shared .M1 .Unlock ()
353
- shared .M1 .Lock ()
354
-
355
- for _ , v := range buf {
356
- if _ , err := safeStdout .WriteString (v ); err != nil {
357
- fmt .Println (err )
358
- }
359
- }
333
+ b .WriteString (aurora .Gray (9 , date ).String ())
334
+ b .WriteString (" " )
335
+ b .WriteString (stylizedLevel )
336
+ b .WriteString (" " )
337
+ b .WriteString (aurora .Gray (12 , "app:" ).String ())
338
+ b .WriteString (aurora .Italic (l .AppName ).String ())
339
+ b .WriteString (" [ " )
360
340
361
341
size := 0
362
342
@@ -390,36 +370,38 @@ func (l *Logger) writePretty(level shared.LogLevel, m *MetaFields, args *[]inter
390
370
size = size + len (s )
391
371
}
392
372
393
- if _ , err := safeStdout .WriteString (s ); err != nil {
394
- WriteToStderr ("771c710b-aba2-46ef-9126-c26d3dfe7925" , err )
373
+ if _ , err := b .WriteString (s ); err != nil {
374
+ writeToStderr ("771c710b-aba2-46ef-9126-c26d3dfe7925" , err )
395
375
}
396
376
397
377
if ! primitive && (level == shared .TRACE || level == shared .DEBUG ) {
398
378
399
- if _ , err := safeStdout .WriteString ("\n " ); err != nil {
400
- WriteToStderr ("18614292-658f-42a5-81e7-593e941ea857" , err )
379
+ if _ , err := b .WriteString ("\n " ); err != nil {
380
+ writeToStderr ("18614292-658f-42a5-81e7-593e941ea857" , err )
401
381
}
402
382
403
- if _ , err := safeStdout .WriteString (fmt .Sprintf ("sprintf: %+v" , v )); err != nil {
404
- WriteToStderr ("2a795ef2-65bb-4a03-9808-b072e4497d73" , err )
383
+ if _ , err := b .WriteString (fmt .Sprintf ("info as sprintf: %+v" , v )); err != nil {
384
+ writeToStderr ("2a795ef2-65bb-4a03-9808-b072e4497d73" , err )
405
385
}
406
386
407
- safeStdout .Write ([]byte ("json:" ))
387
+ b .Write ([]byte ("json:" ))
408
388
if x , err := json .Marshal (v ); err == nil {
409
- if _ , err := safeStdout .Write (x ); err != nil {
410
- WriteToStderr ("err:56831878-8d63-45f4-905b-d1b3bbac2152:" , err )
389
+ if _ , err := b .Write (x ); err != nil {
390
+ writeToStderr ("err:56831878-8d63-45f4-905b-d1b3bbac2152:" , err )
411
391
}
412
392
} else {
413
- WriteToStderr ("err:70bf10e0-6e69-4a3b-bf64-08f6d20c4580:" , err )
393
+ writeToStderr ("err:70bf10e0-6e69-4a3b-bf64-08f6d20c4580:" , err )
414
394
}
415
395
416
396
}
417
397
418
398
}
419
399
420
- if _ , err := safeStdout .WriteString ("\n " ); err != nil {
421
- WriteToStderr ("f834d14a-9735-4fd6-9389-f79144044746" , err )
400
+ if _ , err := b .WriteString (" ] \n " ); err != nil {
401
+ writeToStderr ("f834d14a-9735-4fd6-9389-f79144044746" , err )
422
402
}
403
+
404
+ return & b
423
405
}
424
406
425
407
func (l * Logger ) writeJSON (level shared.LogLevel , mf * MetaFields , args * []interface {}) {
@@ -429,7 +411,11 @@ func (l *Logger) writeJSON(level shared.LogLevel, mf *MetaFields, args *[]interf
429
411
var strLevel = shared .LevelToString [level ]
430
412
var pid = shared .PID
431
413
432
- go func () {
414
+ if mf == nil {
415
+ mf = NewMetaFields (& MF {})
416
+ }
417
+
418
+ shared .StdioPool .Run (func (g * sync.WaitGroup ) {
433
419
434
420
// TODO: maybe manually generating JSON is better? prob not worth it
435
421
buf , err := json .Marshal ([8 ]interface {}{"@bunion:v1" , l .AppName , strLevel , pid , l .HostName , date , mf .m , args })
@@ -456,6 +442,7 @@ func (l *Logger) writeJSON(level shared.LogLevel, mf *MetaFields, args *[]interf
456
442
457
443
if err != nil {
458
444
fmt .Println (errors .New ("Json-Logging: could not marshal the slice: " + err .Error ()))
445
+ g .Done ()
459
446
return
460
447
}
461
448
}
@@ -464,16 +451,17 @@ func (l *Logger) writeJSON(level shared.LogLevel, mf *MetaFields, args *[]interf
464
451
safeStdout .Write (buf )
465
452
safeStdout .Write ([]byte ("\n " ))
466
453
shared .M1 .Unlock ()
454
+ g .Done ()
467
455
468
- }( )
456
+ })
469
457
470
458
}
471
459
472
460
func (l * Logger ) writeSwitch (level shared.LogLevel , m * MetaFields , args * []interface {}) {
473
461
if l .IsLoggingJSON {
474
462
l .writeJSON (level , m , args )
475
463
} else {
476
- l .writePretty (level , m , args )
464
+ l .getPrettyString (level , m , args )
477
465
}
478
466
}
479
467
0 commit comments