mirror of
https://github.com/superseriousbusiness/gotosocial.git
synced 2025-02-05 07:37:02 +01:00
log OTEL internal logs
This commit is contained in:
parent
865b3aeaac
commit
25b59e74ca
4 changed files with 169 additions and 1 deletions
2
go.mod
2
go.mod
|
@ -34,6 +34,7 @@ require (
|
|||
github.com/gin-contrib/gzip v1.0.1
|
||||
github.com/gin-contrib/sessions v1.0.1
|
||||
github.com/gin-gonic/gin v1.10.0
|
||||
github.com/go-logr/logr v1.4.1
|
||||
github.com/go-playground/form/v4 v4.2.1
|
||||
github.com/go-swagger/go-swagger v0.31.0
|
||||
github.com/google/go-cmp v0.6.0
|
||||
|
@ -122,7 +123,6 @@ require (
|
|||
github.com/go-fed/httpsig v1.1.0 // indirect
|
||||
github.com/go-ini/ini v1.67.0 // indirect
|
||||
github.com/go-jose/go-jose/v4 v4.0.2 // indirect
|
||||
github.com/go-logr/logr v1.4.1 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/go-openapi/analysis v0.23.0 // indirect
|
||||
github.com/go-openapi/errors v0.22.0 // indirect
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/go-logr/logr"
|
||||
"log/syslog"
|
||||
"os"
|
||||
"strings"
|
||||
|
@ -313,3 +314,98 @@ func args(count int) string {
|
|||
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
func toFields(keysAndValues ...any) []kv.Field {
|
||||
fields := make([]kv.Field, 0, (len(keysAndValues)+1)/2) // Preallocate slice to half of the input length plus one for odd cases.
|
||||
for i := 0; i < len(keysAndValues); i += 2 {
|
||||
if i+1 < len(keysAndValues) {
|
||||
fields = append(fields, kv.Field{
|
||||
K: fmt.Sprint(keysAndValues[i]),
|
||||
V: keysAndValues[i+1],
|
||||
})
|
||||
} else {
|
||||
fields = append(fields, kv.Field{
|
||||
K: fmt.Sprint(keysAndValues[i]),
|
||||
V: nil,
|
||||
})
|
||||
}
|
||||
}
|
||||
return fields
|
||||
}
|
||||
|
||||
// int log level mapping from https://pkg.go.dev/go.opentelemetry.io/otel/internal/global#SetLogger
|
||||
// "To see Warn messages use a logger with `l.V(1).Enabled() == true`
|
||||
// To see Info messages use a logger with `l.V(4).Enabled() == true`
|
||||
// To see Debug messages use a logger with `l.V(8).Enabled() == true`."
|
||||
func otelLogLevelToGoLoggerLevel(lvl int) level.LEVEL {
|
||||
switch lvl {
|
||||
case 0:
|
||||
return level.ERROR
|
||||
case 1:
|
||||
return level.WARN
|
||||
case 4:
|
||||
return level.INFO
|
||||
case 8:
|
||||
return level.DEBUG
|
||||
default:
|
||||
return level.INFO
|
||||
}
|
||||
}
|
||||
|
||||
type LogrSink struct {
|
||||
ctx context.Context
|
||||
fields []kv.Field
|
||||
name string
|
||||
}
|
||||
|
||||
// Ensure Logger implements logr.LogSink
|
||||
var _ logr.LogSink = &LogrSink{}
|
||||
|
||||
func (l LogrSink) Init(_ logr.RuntimeInfo) {
|
||||
return
|
||||
}
|
||||
|
||||
func (l LogrSink) Enabled(level int) bool {
|
||||
return otelLogLevelToGoLoggerLevel(level) <= loglvl
|
||||
}
|
||||
|
||||
func (l LogrSink) Info(level int, msg string, keysAndValues ...any) {
|
||||
fields := toFields(keysAndValues...)
|
||||
logf(l.ctx, 5, otelLogLevelToGoLoggerLevel(level), fields, msg)
|
||||
}
|
||||
|
||||
func (l LogrSink) Error(_ error, msg string, keysAndValues ...any) {
|
||||
fields := toFields(keysAndValues...)
|
||||
logf(l.ctx, 5, level.ERROR, fields, msg)
|
||||
}
|
||||
|
||||
func (l LogrSink) WithValues(keysAndValues ...any) logr.LogSink {
|
||||
fields := l.fields
|
||||
fields = append(fields, toFields(keysAndValues...)...)
|
||||
return &LogrSink{
|
||||
ctx: l.ctx,
|
||||
fields: fields,
|
||||
name: l.name,
|
||||
}
|
||||
}
|
||||
|
||||
func (l LogrSink) WithName(name string) logr.LogSink {
|
||||
newName := l.name
|
||||
if newName != "" {
|
||||
newName += "/"
|
||||
}
|
||||
newName += name
|
||||
return &LogrSink{
|
||||
ctx: l.ctx,
|
||||
fields: l.fields,
|
||||
name: newName,
|
||||
}
|
||||
}
|
||||
|
||||
func NewLogrSink() logr.LogSink {
|
||||
return &LogrSink{}
|
||||
}
|
||||
|
||||
func NewLogrLogger() logr.Logger {
|
||||
return logr.New(NewLogrSink())
|
||||
}
|
||||
|
|
69
internal/log/log_test.go
Normal file
69
internal/log/log_test.go
Normal file
|
@ -0,0 +1,69 @@
|
|||
// GoToSocial
|
||||
// Copyright (C) GoToSocial Authors admin@gotosocial.org
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package log
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"codeberg.org/gruf/go-kv"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestToFields(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
keysAndValues []any
|
||||
expectedFields []kv.Field
|
||||
}{
|
||||
{
|
||||
name: "Even number of elements",
|
||||
keysAndValues: []any{"count", 2, "total_dropped", 0},
|
||||
expectedFields: []kv.Field{
|
||||
{K: "count", V: 2},
|
||||
{K: "total_dropped", V: 0},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Odd number of elements",
|
||||
keysAndValues: []any{"count", 2, "whatever"},
|
||||
expectedFields: []kv.Field{
|
||||
{K: "count", V: 2},
|
||||
{K: "whatever", V: nil},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Empty input",
|
||||
keysAndValues: []any{},
|
||||
expectedFields: []kv.Field{},
|
||||
},
|
||||
{
|
||||
name: "Single element",
|
||||
keysAndValues: []any{"single"},
|
||||
expectedFields: []kv.Field{
|
||||
{K: "single", V: nil},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
actualFields := toFields(tt.keysAndValues...)
|
||||
assert.Equal(t, tt.expectedFields, actualFields)
|
||||
})
|
||||
}
|
||||
}
|
|
@ -55,6 +55,9 @@ func Initialize() error {
|
|||
|
||||
insecure := config.GetTracingInsecureTransport()
|
||||
|
||||
// Log internal OTEL logs
|
||||
otel.SetLogger(log.NewLogrLogger())
|
||||
|
||||
var tpo trace.TracerProviderOption
|
||||
switch config.GetTracingTransport() {
|
||||
case "grpc":
|
||||
|
|
Loading…
Reference in a new issue