Desktop integration (#2073)

* Open stash in system tray on Windows/MacOS
* Add desktop notifications
* MacOS Bundling
* Add binary icon

Co-authored-by: WithoutPants <53250216+WithoutPants@users.noreply.github.com>
This commit is contained in:
kermieisinthehouse
2022-02-02 16:20:34 -08:00
committed by GitHub
parent e48b2ba3e8
commit 0e514183a7
306 changed files with 29542 additions and 4792 deletions

View File

@@ -341,7 +341,7 @@ If your writer might be slow or not thread-safe and you need your log producers
wr := diode.NewWriter(os.Stdout, 1000, 10*time.Millisecond, func(missed int) {
fmt.Printf("Logger Dropped %d messages", missed)
})
log := zerolog.New(w)
log := zerolog.New(wr)
log.Print("test")
```
@@ -435,7 +435,7 @@ c := alice.New()
c = c.Append(hlog.NewHandler(log))
// Install some provided extra handler to set some request's context fields.
// Thanks to those handler, all our logs will come with some pre-populated fields.
// Thanks to that handler, all our logs will come with some prepopulated fields.
c = c.Append(hlog.AccessHandler(func(r *http.Request, status, size int, duration time.Duration) {
hlog.FromRequest(r).Info().
Str("method", r.Method).
@@ -474,7 +474,7 @@ if err := http.ListenAndServe(":8080", nil); err != nil {
Some settings can be changed and will by applied to all loggers:
* `log.Logger`: You can set this value to customize the global logger (the one used by package level methods).
* `zerolog.SetGlobalLevel`: Can raise the minimum level of all loggers. Set this to `zerolog.Disabled` to disable logging altogether (quiet mode).
* `zerolog.SetGlobalLevel`: Can raise the minimum level of all loggers. Call this with `zerolog.Disabled` to disable logging altogether (quiet mode).
* `zerolog.DisableSampling`: If argument is `true`, all sampled loggers will stop sampling and issue 100% of their log events.
* `zerolog.TimestampFieldName`: Can be set to customize `Timestamp` field name.
* `zerolog.LevelFieldName`: Can be set to customize level field name.
@@ -497,13 +497,17 @@ Some settings can be changed and will by applied to all loggers:
### Advanced Fields
* `Err`: Takes an `error` and render it as a string using the `zerolog.ErrorFieldName` field name.
* `Timestamp`: Insert a timestamp field with `zerolog.TimestampFieldName` field name and formatted using `zerolog.TimeFieldFormat`.
* `Time`: Adds a field with the time formated with the `zerolog.TimeFieldFormat`.
* `Dur`: Adds a field with a `time.Duration`.
* `Err`: Takes an `error` and renders it as a string using the `zerolog.ErrorFieldName` field name.
* `Timestamp`: Inserts a timestamp field with `zerolog.TimestampFieldName` field name, formatted using `zerolog.TimeFieldFormat`.
* `Time`: Adds a field with time formatted with `zerolog.TimeFieldFormat`.
* `Dur`: Adds a field with `time.Duration`.
* `Dict`: Adds a sub-key/value as a field of the event.
* `RawJSON`: Adds a field with an already encoded JSON (`[]byte`)
* `Hex`: Adds a field with value formatted as a hexadecimal string (`[]byte`)
* `Interface`: Uses reflection to marshal the type.
Most fields are also available in the slice format (`Strs` for `[]string`, `Errs` for `[]error` etc.)
## Binary Encoding
In addition to the default JSON encoding, `zerolog` can produce binary logs using [CBOR](http://cbor.io) encoding. The choice of encoding can be decided at compile time using the build tag `binary_log` as follows:

View File

@@ -61,6 +61,7 @@ func newEvent(w LevelWriter, level Level) *Event {
e.buf = enc.AppendBeginMarker(e.buf)
e.w = w
e.level = level
e.stack = false
return e
}
@@ -317,7 +318,6 @@ func (e *Event) Errs(key string, errs []error) *Event {
// Err adds the field "error" with serialized err to the *Event context.
// If err is nil, no field is added.
// To customize the key name, change zerolog.ErrorFieldName.
//
// To customize the key name, change zerolog.ErrorFieldName.
//

View File

@@ -0,0 +1,35 @@
// +build !386
package cbor
import (
"encoding/hex"
"testing"
)
var enc2 = Encoder{}
var integerTestCases_64bit = []struct {
val int
binary string
}{
// Value in 8 bytes.
{0xabcd100000000, "\x1b\x00\x0a\xbc\xd1\x00\x00\x00\x00"},
{1000000000000, "\x1b\x00\x00\x00\xe8\xd4\xa5\x10\x00"},
// Value in 8 bytes.
{-0xabcd100000001, "\x3b\x00\x0a\xbc\xd1\x00\x00\x00\x00"},
{-1000000000001, "\x3b\x00\x00\x00\xe8\xd4\xa5\x10\x00"},
}
func TestAppendInt_64bit(t *testing.T) {
for _, tc := range integerTestCases_64bit {
s := enc2.AppendInt([]byte{}, tc.val)
got := string(s)
if got != tc.binary {
t.Errorf("AppendInt(0x%x)=0x%s, want: 0x%s",
tc.val, hex.EncodeToString(s),
hex.EncodeToString([]byte(tc.binary)))
}
}
}

View File

@@ -4,9 +4,8 @@ type Encoder struct{}
// AppendKey appends a new key to the output JSON.
func (e Encoder) AppendKey(dst []byte, key string) []byte {
if len(dst) > 1 && dst[len(dst)-1] != '{' {
if dst[len(dst)-1] != '{' {
dst = append(dst, ',')
}
dst = e.AppendString(dst, key)
return append(dst, ':')
}
return append(e.AppendString(dst, key), ':')
}

View File

@@ -379,11 +379,10 @@ func (Encoder) AppendObjectData(dst []byte, o []byte) []byte {
// to separate with existing content OR
// 3. existing content has already other fields
if o[0] == '{' {
if len(dst) == 0 {
o = o[1:]
} else {
o[0] = ','
if len(dst) > 1 {
dst = append(dst, ',')
}
o = o[1:]
} else if len(dst) > 1 {
dst = append(dst, ',')
}

View File

@@ -234,6 +234,10 @@ func (l Logger) With() Context {
l.context = make([]byte, 0, 500)
if context != nil {
l.context = append(l.context, context...)
} else {
// This is needed for AppendKey to not check len of input
// thus making it inlinable
l.context = enc.AppendBeginMarker(l.context)
}
return Context{l}
}
@@ -415,7 +419,7 @@ func (l *Logger) newEvent(level Level, done func(string)) *Event {
if level != NoLevel {
e.Str(LevelFieldName, LevelFieldMarshalFunc(level))
}
if l.context != nil && len(l.context) > 0 {
if l.context != nil && len(l.context) > 1 {
e.buf = enc.AppendObjectData(e.buf, l.context)
}
return e

View File

@@ -29,7 +29,7 @@ type syncWriter struct {
// This syncer can be the call to writer's Write method is not thread safe.
// Note that os.File Write operation is using write() syscall which is supposed
// to be thread-safe on POSIX systems. So there is no need to use this with
// os.File on such systems as zerolog guaranties to issue a single Write call
// os.File on such systems as zerolog guarantees to issue a single Write call
// per log event.
func SyncWriter(w io.Writer) io.Writer {
if lw, ok := w.(LevelWriter); ok {