mirror of
https://github.com/foomo/keel.git
synced 2025-10-16 12:35:34 +00:00
feat: switch to semconv
This commit is contained in:
parent
80d236f6a2
commit
b4b775681a
@ -7,6 +7,7 @@ import (
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
|
||||
semconv "go.opentelemetry.io/otel/semconv/v1.37.0"
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/foomo/keel/log"
|
||||
@ -58,7 +59,7 @@ func (s *ServiceHTTP) Start(ctx context.Context) error {
|
||||
ip = "0.0.0.0"
|
||||
}
|
||||
|
||||
fields = append(fields, log.FNetHostIP(ip), log.FNetHostPort(port))
|
||||
fields = append(fields, log.Attributes(semconv.ServerAddress(ip), semconv.ServerPortKey.String(port))...)
|
||||
}
|
||||
|
||||
s.l.Info("starting http test service", fields...)
|
||||
|
||||
@ -18,22 +18,22 @@ const (
|
||||
JSONKey = "json"
|
||||
)
|
||||
|
||||
// FNum - returns zap field
|
||||
// FNum creates a zap.Field with a given number under the key "num".
|
||||
func FNum(num int) zap.Field {
|
||||
return zap.Int(NumKey, num)
|
||||
}
|
||||
|
||||
// FName - returns zap field
|
||||
// FName creates a zap.Field with a given string under the key "name".
|
||||
func FName(name string) zap.Field {
|
||||
return zap.String(NameKey, name)
|
||||
}
|
||||
|
||||
// FValue - returns zap field
|
||||
// FValue creates a zap.Field with a given value under the key "value".
|
||||
func FValue(value interface{}) zap.Field {
|
||||
return zap.String(ValueKey, fmt.Sprintf("%v", value))
|
||||
}
|
||||
|
||||
// FJSON - returns zap field
|
||||
// FJSON creates a zap.Field with a given value under the key "json".
|
||||
func FJSON(v interface{}) zap.Field {
|
||||
if out, err := json.Marshal(v); err != nil {
|
||||
return zap.String(JSONKey+"_error", err.Error())
|
||||
|
||||
@ -5,24 +5,32 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
CodeInstanceKey = "code_instance"
|
||||
CodePackageKey = "code_package"
|
||||
CodeMethodKey = "code_method"
|
||||
CodeLineKey = "code_line"
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
CodePackageKey = "code_package"
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
CodeMethodKey = "code_method"
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
CodeLineKey = "code_line"
|
||||
)
|
||||
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
func FCodeInstance(v string) zap.Field {
|
||||
return zap.String(CodeInstanceKey, v)
|
||||
}
|
||||
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
func FCodePackage(v string) zap.Field {
|
||||
return zap.String(CodePackageKey, v)
|
||||
}
|
||||
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
func FCodeMethod(v string) zap.Field {
|
||||
return zap.String(CodeMethodKey, v)
|
||||
}
|
||||
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
func FCodeLine(v int) zap.Field {
|
||||
return zap.Int(CodeLineKey, v)
|
||||
}
|
||||
|
||||
@ -7,28 +7,37 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
DurationKey = "duration"
|
||||
DurationSecKey = "duration_sec"
|
||||
DurationMinKey = "duration_min"
|
||||
// DurationKey - generic duration attribute
|
||||
DurationKey = "duration"
|
||||
// DurationSecKey - duration in seconds
|
||||
DurationSecKey = "duration_sec"
|
||||
// DurationMinKey - duration in minutes
|
||||
DurationMinKey = "duration_min"
|
||||
// DurationHourKey - duration in hours
|
||||
DurationHourKey = "duration_hour"
|
||||
)
|
||||
|
||||
// FDuration creates a zap.Field with a given time.Duration converted to milliseconds under the key "duration".
|
||||
func FDuration(duration time.Duration) zap.Field {
|
||||
return zap.Float64(DurationKey, float64(duration)/float64(time.Millisecond))
|
||||
return zap.Int64(DurationKey, duration.Milliseconds())
|
||||
}
|
||||
|
||||
// FDurationSec creates a zap.Field with a given time.Duration converted to seconds under the key "duration_sec".
|
||||
func FDurationSec(duration time.Duration) zap.Field {
|
||||
return zap.Float64(DurationSecKey, float64(duration)/float64(time.Second))
|
||||
return zap.Float64(DurationSecKey, duration.Seconds())
|
||||
}
|
||||
|
||||
// FDurationMin creates a zap.Field with a given time.Duration converted to minutes under the key "duration_min".
|
||||
func FDurationMin(duration time.Duration) zap.Field {
|
||||
return zap.Float64(DurationMinKey, float64(duration)/float64(time.Minute))
|
||||
return zap.Float64(DurationMinKey, duration.Minutes())
|
||||
}
|
||||
|
||||
// FDurationHour creates a zap.Field with a given time.Duration converted to hours under the key "duration_hour".
|
||||
func FDurationHour(duration time.Duration) zap.Field {
|
||||
return zap.Float64(DurationHourKey, float64(duration)/float64(time.Hour))
|
||||
return zap.Float64(DurationHourKey, duration.Hours())
|
||||
}
|
||||
|
||||
// FDurationFn returns a function that returns a zap.Field with a given time.Duration converted to milliseconds under the key "duration".
|
||||
func FDurationFn() func() zap.Field {
|
||||
start := time.Now()
|
||||
|
||||
|
||||
@ -5,110 +5,109 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
// HTTPServerNameKey represents the name of the service handling the request
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
HTTPServerNameKey = "http_server_name"
|
||||
|
||||
// HTTPMethodKey represents the HTTP request method.
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
HTTPMethodKey = "http_method"
|
||||
|
||||
// HTTPTargetKey represents the full request target as passed in a HTTP
|
||||
// request line or equivalent, e.g. "/path/12314/?q=ddds#123".
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
HTTPTargetKey = "http_target"
|
||||
|
||||
// HTTPHostKey represents the value of the HTTP host header.
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
HTTPHostKey = "http_host"
|
||||
|
||||
// HTTPStatusCodeKey represents the HTTP response status code.
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
HTTPStatusCodeKey = "http_status_code"
|
||||
|
||||
// HTTPUserAgentKey represents the Value of the HTTP User-Agent header sent by the client.
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
HTTPUserAgentKey = "http_user_agent"
|
||||
|
||||
// HTTPClientIPKey represents the IP address of the original client behind all proxies,
|
||||
// if known (e.g. from X-Forwarded-For).
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
HTTPClientIPKey = "http_client_ip"
|
||||
|
||||
// HTTPRequestContentLengthKey represents the size of the request payload body in bytes.
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
HTTPRequestContentLengthKey = "http_read_bytes"
|
||||
|
||||
// HTTPWroteBytesKey represents the size of the response payload body in bytes.
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
HTTPWroteBytesKey = "http_wrote_bytes" // #nosec
|
||||
|
||||
// HTTPSchemeKey represents the URI scheme identifying the used protocol.
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
HTTPSchemeKey = "http_scheme"
|
||||
|
||||
// HTTPFlavorKey represents the Kind of HTTP protocol used.
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
HTTPFlavorKey = "http_flavor"
|
||||
|
||||
// HTTPRequestIDKey represents the HTTP request id if known (e.g. from X-Request-ID).
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
HTTPRequestIDKey = "http_request_id"
|
||||
|
||||
// HTTPSessionIDKey represents the HTTP session id if known (e.g. from X-Session-ID).
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
HTTPSessionIDKey = "http_session_id"
|
||||
|
||||
// HTTPTrackingIDKey represents the HTTP tracking id if known (e.g. from X-Tracking-ID).
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
HTTPTrackingIDKey = "http_tracking_id"
|
||||
|
||||
// HTTPRefererKey identifies the address of the web page (i.e., the URI or IRI), from which the resource has been requested.
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
HTTPRefererKey = "http_referer"
|
||||
)
|
||||
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
func FHTTPServerName(id string) zap.Field {
|
||||
return zap.String(HTTPServerNameKey, id)
|
||||
}
|
||||
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
func FHTTPRequestID(id string) zap.Field {
|
||||
return zap.String(HTTPRequestIDKey, id)
|
||||
}
|
||||
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
func FHTTPSessionID(id string) zap.Field {
|
||||
return zap.String(HTTPSessionIDKey, id)
|
||||
}
|
||||
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
func FHTTPTrackingID(id string) zap.Field {
|
||||
return zap.String(HTTPTrackingIDKey, id)
|
||||
}
|
||||
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
func FHTTPRequestContentLength(bytes int64) zap.Field {
|
||||
return zap.Int64(HTTPRequestContentLengthKey, bytes)
|
||||
}
|
||||
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
func FHTTPWroteBytes(bytes int64) zap.Field {
|
||||
return zap.Int64(HTTPWroteBytesKey, bytes)
|
||||
}
|
||||
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
func FHTTPStatusCode(status int) zap.Field {
|
||||
return zap.Int(HTTPStatusCodeKey, status)
|
||||
}
|
||||
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
func FHTTPTarget(target string) zap.Field {
|
||||
return zap.String(HTTPTargetKey, target)
|
||||
}
|
||||
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
func FHTTPClientIP(clientIP string) zap.Field {
|
||||
return zap.String(HTTPClientIPKey, clientIP)
|
||||
}
|
||||
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
func FHTTPFlavor(flavor string) zap.Field {
|
||||
return zap.String(HTTPFlavorKey, flavor)
|
||||
}
|
||||
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
func FHTTPScheme(scheme string) zap.Field {
|
||||
return zap.String(HTTPSchemeKey, scheme)
|
||||
}
|
||||
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
func FHTTPUserAgent(userAgent string) zap.Field {
|
||||
return zap.String(HTTPUserAgentKey, userAgent)
|
||||
}
|
||||
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
func FHTTPReferer(host string) zap.Field {
|
||||
return zap.String(HTTPRefererKey, host)
|
||||
}
|
||||
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
func FHTTPHost(host string) zap.Field {
|
||||
return zap.String(HTTPHostKey, host)
|
||||
}
|
||||
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
func FHTTPMethod(name string) zap.Field {
|
||||
return zap.String(HTTPMethodKey, name)
|
||||
}
|
||||
|
||||
@ -1,11 +0,0 @@
|
||||
package log
|
||||
|
||||
import (
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
)
|
||||
|
||||
const (
|
||||
KeelServiceTypeKey = attribute.Key("keel.service.type")
|
||||
KeelServiceNameKey = attribute.Key("keel.service.name")
|
||||
KeelServiceInstKey = attribute.Key("keel.service.inst")
|
||||
)
|
||||
@ -1,65 +1,89 @@
|
||||
package log
|
||||
|
||||
import (
|
||||
semconv "go.opentelemetry.io/otel/semconv/v1.37.0"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
const (
|
||||
MessagingSystemKey = "messaging_system"
|
||||
MessagingDestinationKey = "messaging_destination"
|
||||
MessagingDestinationKindKey = "messaging_destination_kind"
|
||||
MessagingProtocolKey = "messaging_protocol"
|
||||
MessagingProtocolVersionKey = "messaging_protocol_version"
|
||||
MessagingURLKey = "messaging_url"
|
||||
MessagingMessageIDKey = "messaging_message_id"
|
||||
MessagingConversationIDKey = "messaging_conversation_id"
|
||||
MessagingMessagePayloadSizeBytesKey = "messaging_message_payload_size_bytes"
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
MessagingSystemKey = "messaging_system"
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
MessagingDestinationKey = "messaging_destination"
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
MessagingDestinationKindKey = "messaging_destination_kind"
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
MessagingProtocolKey = "messaging_protocol"
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
MessagingProtocolVersionKey = "messaging_protocol_version"
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
MessagingURLKey = "messaging_url"
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
MessagingMessageIDKey = "messaging_message_id"
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
MessagingConversationIDKey = "messaging_conversation_id"
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
MessagingMessagePayloadSizeBytesKey = "messaging_message_payload_size_bytes"
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
MessagingMessagePayloadCompressedSizeBytesKey = "messaging_message_payload_compressed_size_bytes"
|
||||
)
|
||||
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
type MessagingDestinationKind string
|
||||
|
||||
const (
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
MessagingDestinationKindQueue MessagingDestinationKind = "queue"
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
MessagingDestinationKindTopic MessagingDestinationKind = "topic"
|
||||
)
|
||||
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
func FMessagingSystem(value string) zap.Field {
|
||||
return zap.String(MessagingSystemKey, value)
|
||||
}
|
||||
|
||||
// Deprecated: use semconv.MessagingDestinationName instead.
|
||||
func FMessagingDestination(value string) zap.Field {
|
||||
return zap.String(MessagingDestinationKey, value)
|
||||
return Attribute(semconv.MessagingDestinationName(value))
|
||||
}
|
||||
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
func FMessagingDestinationKind(value MessagingDestinationKind) zap.Field {
|
||||
return zap.String(MessagingDestinationKindKey, string(value))
|
||||
}
|
||||
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
func FMessagingProtocol(value string) zap.Field {
|
||||
return zap.String(MessagingProtocolKey, value)
|
||||
}
|
||||
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
func FMessagingProtocolVersion(value string) zap.Field {
|
||||
return zap.String(MessagingProtocolVersionKey, value)
|
||||
}
|
||||
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
func FMessagingURL(value string) zap.Field {
|
||||
return zap.String(MessagingURLKey, value)
|
||||
}
|
||||
|
||||
// Deprecated: use semconv.MessagingMessageID instead.
|
||||
func FMessagingMessageID(value string) zap.Field {
|
||||
return zap.String(MessagingMessageIDKey, value)
|
||||
return Attribute(semconv.MessagingMessageID(value))
|
||||
}
|
||||
|
||||
// Deprecated: use semconv.MessagingMessageConversationID instead.
|
||||
func FMessagingConversationID(value string) zap.Field {
|
||||
return zap.String(MessagingConversationIDKey, value)
|
||||
return Attribute(semconv.MessagingMessageConversationID(value))
|
||||
}
|
||||
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
func FMessagingMessagePayloadSizeBytes(value string) zap.Field {
|
||||
return zap.String(MessagingMessagePayloadSizeBytesKey, value)
|
||||
}
|
||||
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
func FMessagingMessagePayloadCompressedSizeBytes(value string) zap.Field {
|
||||
return zap.String(MessagingMessagePayloadCompressedSizeBytesKey, value)
|
||||
}
|
||||
|
||||
@ -1,21 +1,23 @@
|
||||
package log
|
||||
|
||||
import (
|
||||
semconv "go.opentelemetry.io/otel/semconv/v1.37.0"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
const (
|
||||
// NetHostIPKey represents the local host IP. Useful in case of a multi-IP host.
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
NetHostIPKey = "net_host_ip"
|
||||
|
||||
// NetHostPortKey represents the local host port.
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
NetHostPortKey = "net_host_port"
|
||||
)
|
||||
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
func FNetHostIP(ip string) zap.Field {
|
||||
return zap.String(NetHostIPKey, ip)
|
||||
return Attribute(semconv.HostIP(ip))
|
||||
}
|
||||
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
func FNetHostPort(port string) zap.Field {
|
||||
return zap.String(NetHostPortKey, port)
|
||||
}
|
||||
|
||||
@ -5,58 +5,53 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
// PeerServiceKey represents the ServiceNameKey name of the remote service.
|
||||
// Should equal the actual `service.name` resource attribute of the remote service, if any.
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
PeerServiceKey = "peer_service"
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
ServiceTypeKey = "service_type"
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
ServiceNameKey = "service_name"
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
ServiceMethodKey = "service_method"
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
ServiceNamespaceKey = "service_namespace"
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
ServiceInstanceIDKey = "service_instance.id"
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
ServiceVersionKey = "service_version"
|
||||
)
|
||||
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
func FPeerService(name string) zap.Field {
|
||||
return zap.String(PeerServiceKey, name)
|
||||
}
|
||||
|
||||
const (
|
||||
ServiceTypeKey = "service_type"
|
||||
|
||||
// ServiceNameKey represents the NameKey of the service.
|
||||
ServiceNameKey = "service_name"
|
||||
|
||||
// ServiceMethodKey represents the Method of the service.
|
||||
ServiceMethodKey = "service_method"
|
||||
|
||||
// ServiceNamespaceKey represents a namespace for `service.name`. This needs to
|
||||
// have meaning that helps to distinguish a group of services. For example, the
|
||||
// team name that owns a group of services. `service.name` is expected to be
|
||||
// unique within the same namespace.
|
||||
ServiceNamespaceKey = "service_namespace"
|
||||
|
||||
// ServiceInstanceIDKey represents a unique identifier of the service instance. In conjunction
|
||||
// with the `service.name` and `service.namespace` this must be unique.
|
||||
ServiceInstanceIDKey = "service_instance.id"
|
||||
|
||||
// ServiceVersionKey represents the version of the service API.
|
||||
ServiceVersionKey = "service_version"
|
||||
)
|
||||
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
func FServiceType(name string) zap.Field {
|
||||
return zap.String(ServiceTypeKey, name)
|
||||
}
|
||||
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
func FServiceName(name string) zap.Field {
|
||||
return zap.String(ServiceNameKey, name)
|
||||
}
|
||||
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
func FServiceNamespace(namespace string) zap.Field {
|
||||
return zap.String(ServiceNamespaceKey, namespace)
|
||||
}
|
||||
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
func FServiceInstanceID(id string) zap.Field {
|
||||
return zap.String(ServiceInstanceIDKey, id)
|
||||
}
|
||||
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
func FServiceVersion(version string) zap.Field {
|
||||
return zap.String(ServiceVersionKey, version)
|
||||
}
|
||||
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
func FServiceMethod(method string) zap.Field {
|
||||
return zap.String(ServiceMethodKey, method)
|
||||
}
|
||||
|
||||
@ -5,14 +5,18 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
StreamQueueKey = "queue"
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
StreamQueueKey = "queue"
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
StreamSubjectKey = "subject"
|
||||
)
|
||||
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
func FStreamQueue(queue string) zap.Field {
|
||||
return zap.String(StreamQueueKey, queue)
|
||||
}
|
||||
|
||||
// Deprecated: use semconv messaging attributes instead.
|
||||
func FStreamSubject(name string) zap.Field {
|
||||
return zap.String(StreamSubjectKey, name)
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@ package log
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
semconv "go.opentelemetry.io/otel/semconv/v1.37.0"
|
||||
"go.uber.org/zap"
|
||||
@ -41,8 +42,8 @@ func NewLogger(level, encoding string) *zap.Logger {
|
||||
config.EncoderConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder
|
||||
}
|
||||
|
||||
config.EncoderConfig.CallerKey = string(semconv.CodeFilePathKey)
|
||||
config.EncoderConfig.StacktraceKey = string(semconv.CodeStacktraceKey)
|
||||
config.EncoderConfig.CallerKey = strings.ReplaceAll(string(semconv.CodeFilePathKey), ".", "_")
|
||||
config.EncoderConfig.StacktraceKey = strings.ReplaceAll(string(semconv.CodeStacktraceKey), ".", "_")
|
||||
config.EncoderConfig.EncodeCaller = func(caller zapcore.EntryCaller, encoder zapcore.PrimitiveArrayEncoder) {
|
||||
encoder.AppendString(caller.File)
|
||||
}
|
||||
|
||||
48
log/otel.go
Normal file
48
log/otel.go
Normal file
@ -0,0 +1,48 @@
|
||||
package log
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
func Attributes(attrs ...attribute.KeyValue) []zap.Field {
|
||||
ret := make([]zap.Field, len(attrs))
|
||||
for i, attr := range attrs {
|
||||
ret[i] = Attribute(attr)
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func Attribute(attr attribute.KeyValue) zap.Field {
|
||||
switch attr.Value.Type() {
|
||||
case attribute.BOOL:
|
||||
return zap.Bool(AttributeKey(attr.Key), attr.Value.AsBool())
|
||||
case attribute.BOOLSLICE:
|
||||
return zap.Bools(AttributeKey(attr.Key), attr.Value.AsBoolSlice())
|
||||
case attribute.INT64:
|
||||
return zap.Int64(AttributeKey(attr.Key), attr.Value.AsInt64())
|
||||
case attribute.INT64SLICE:
|
||||
return zap.Int64s(AttributeKey(attr.Key), attr.Value.AsInt64Slice())
|
||||
case attribute.FLOAT64:
|
||||
return zap.Float64(AttributeKey(attr.Key), attr.Value.AsFloat64())
|
||||
case attribute.FLOAT64SLICE:
|
||||
return zap.Float64s(AttributeKey(attr.Key), attr.Value.AsFloat64Slice())
|
||||
case attribute.STRING:
|
||||
return zap.String(AttributeKey(attr.Key), attr.Value.AsString())
|
||||
case attribute.STRINGSLICE:
|
||||
if value := attr.Value.AsStringSlice(); len(value) == 1 {
|
||||
return zap.String(AttributeKey(attr.Key), value[0])
|
||||
} else {
|
||||
return zap.Strings(AttributeKey(attr.Key), value)
|
||||
}
|
||||
default:
|
||||
return zap.Any(AttributeKey(attr.Key), attr.Value.AsInterface())
|
||||
}
|
||||
}
|
||||
|
||||
func AttributeKey(key attribute.Key) string {
|
||||
return strings.ReplaceAll(string(key), ".", "_")
|
||||
}
|
||||
64
log/with.go
64
log/with.go
@ -7,7 +7,9 @@ import (
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
keelsemconv "github.com/foomo/keel/semconv"
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
semconv "go.opentelemetry.io/otel/semconv/v1.37.0"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
"go.uber.org/zap"
|
||||
|
||||
@ -40,7 +42,7 @@ func WithError(l *zap.Logger, err error) *zap.Logger {
|
||||
}
|
||||
|
||||
func WithServiceName(l *zap.Logger, name string) *zap.Logger {
|
||||
return With(l, FServiceName(name))
|
||||
return With(l, Attribute(semconv.ServiceName(name)))
|
||||
}
|
||||
|
||||
func WithTraceID(l *zap.Logger, ctx context.Context) *zap.Logger {
|
||||
@ -56,29 +58,22 @@ func WithHTTPServerName(l *zap.Logger, name string) *zap.Logger {
|
||||
}
|
||||
|
||||
func WithHTTPFlavor(l *zap.Logger, r *http.Request) *zap.Logger {
|
||||
switch r.ProtoMajor {
|
||||
case 1:
|
||||
return With(l, FHTTPFlavor(fmt.Sprintf("1.%d", r.ProtoMinor)))
|
||||
case 2:
|
||||
return With(l, FHTTPFlavor("2"))
|
||||
default:
|
||||
return l
|
||||
}
|
||||
return With(l, Attributes(semconv.NetworkProtocolName("HTTP"), semconv.NetworkProtocolVersion(fmt.Sprintf("%d.%d", r.ProtoMajor, r.ProtoMinor)))...)
|
||||
}
|
||||
|
||||
func WithHTTPScheme(l *zap.Logger, r *http.Request) *zap.Logger {
|
||||
if r.TLS != nil {
|
||||
return With(l, FHTTPScheme("https"))
|
||||
return With(l, Attribute(semconv.URLScheme("https")))
|
||||
} else {
|
||||
return With(l, FHTTPScheme("http"))
|
||||
return With(l, Attribute(semconv.URLScheme("http")))
|
||||
}
|
||||
}
|
||||
|
||||
func WithHTTPSessionID(l *zap.Logger, r *http.Request) *zap.Logger {
|
||||
if id := r.Header.Get("X-Session-Id"); id != "" {
|
||||
return With(l, FHTTPSessionID(id))
|
||||
return With(l, Attribute(semconv.SessionID(id)))
|
||||
} else if id, ok := keelhttpcontext.GetSessionID(r.Context()); ok && id != "" {
|
||||
return With(l, FHTTPSessionID(id))
|
||||
return With(l, Attribute(semconv.SessionID(id)))
|
||||
} else {
|
||||
return l
|
||||
}
|
||||
@ -86,9 +81,9 @@ func WithHTTPSessionID(l *zap.Logger, r *http.Request) *zap.Logger {
|
||||
|
||||
func WithHTTPRequestID(l *zap.Logger, r *http.Request) *zap.Logger {
|
||||
if id := r.Header.Get("X-Request-Id"); id != "" {
|
||||
return With(l, FHTTPRequestID(id))
|
||||
return With(l, Attribute(keelsemconv.HTTPXRequestID(id)))
|
||||
} else if id, ok := keelhttpcontext.GetRequestID(r.Context()); ok && id != "" {
|
||||
return With(l, FHTTPRequestID(id))
|
||||
return With(l, Attribute(keelsemconv.HTTPXRequestID(id)))
|
||||
} else {
|
||||
return l
|
||||
}
|
||||
@ -96,9 +91,9 @@ func WithHTTPRequestID(l *zap.Logger, r *http.Request) *zap.Logger {
|
||||
|
||||
func WithHTTPReferer(l *zap.Logger, r *http.Request) *zap.Logger {
|
||||
if value := r.Header.Get("X-Referer"); value != "" {
|
||||
return With(l, FHTTPReferer(value))
|
||||
return With(l, Attribute(keelsemconv.HTTPXRequestReferer(value)))
|
||||
} else if value := r.Referer(); value != "" {
|
||||
return With(l, FHTTPReferer(value))
|
||||
return With(l, Attribute(keelsemconv.HTTPXRequestReferer(value)))
|
||||
} else {
|
||||
return l
|
||||
}
|
||||
@ -106,19 +101,19 @@ func WithHTTPReferer(l *zap.Logger, r *http.Request) *zap.Logger {
|
||||
|
||||
func WithHTTPHost(l *zap.Logger, r *http.Request) *zap.Logger {
|
||||
if value := r.Header.Get("X-Forwarded-Host"); value != "" {
|
||||
return With(l, FHTTPHost(value))
|
||||
return With(l, Attribute(semconv.HostName(value)))
|
||||
} else if !r.URL.IsAbs() {
|
||||
return With(l, FHTTPHost(r.Host))
|
||||
return With(l, Attribute(semconv.HostName(r.Host)))
|
||||
} else {
|
||||
return With(l, FHTTPHost(r.URL.Host))
|
||||
return With(l, Attribute(semconv.HostName(r.URL.Host)))
|
||||
}
|
||||
}
|
||||
|
||||
func WithHTTPTrackingID(l *zap.Logger, r *http.Request) *zap.Logger {
|
||||
if id := r.Header.Get("X-Tracking-Id"); id != "" {
|
||||
return With(l, FHTTPTrackingID(id))
|
||||
return With(l, Attribute(keelsemconv.TrackingID(id)))
|
||||
} else if id, ok := keelhttpcontext.GetTrackingID(r.Context()); ok && id != "" {
|
||||
return With(l, FHTTPTrackingID(id))
|
||||
return With(l, Attribute(keelsemconv.TrackingID(id)))
|
||||
} else {
|
||||
return l
|
||||
}
|
||||
@ -142,7 +137,7 @@ func WithHTTPClientIP(l *zap.Logger, r *http.Request) *zap.Logger {
|
||||
}
|
||||
|
||||
if clientIP != "" {
|
||||
return With(l, FHTTPClientIP(clientIP))
|
||||
return With(l, Attribute(semconv.ClientAddress(clientIP)))
|
||||
}
|
||||
|
||||
return l
|
||||
@ -159,12 +154,12 @@ func WithHTTPRequest(l *zap.Logger, r *http.Request) *zap.Logger {
|
||||
l = WithHTTPClientIP(l, r)
|
||||
l = WithTraceID(l, r.Context())
|
||||
|
||||
return With(l,
|
||||
FHTTPMethod(r.Method),
|
||||
FHTTPTarget(r.RequestURI),
|
||||
FHTTPUserAgent(r.UserAgent()),
|
||||
FHTTPRequestContentLength(r.ContentLength),
|
||||
)
|
||||
return With(l, Attributes(
|
||||
semconv.URLPath(r.URL.Path),
|
||||
semconv.UserAgentName(r.UserAgent()),
|
||||
semconv.HTTPRequestMethodKey.String(r.Method),
|
||||
semconv.HTTPRequestSizeKey.Int64(r.ContentLength),
|
||||
)...)
|
||||
}
|
||||
|
||||
func WithHTTPRequestOut(l *zap.Logger, r *http.Request) *zap.Logger {
|
||||
@ -176,9 +171,10 @@ func WithHTTPRequestOut(l *zap.Logger, r *http.Request) *zap.Logger {
|
||||
l = WithHTTPFlavor(l, r)
|
||||
l = WithTraceID(l, r.Context())
|
||||
|
||||
return With(l,
|
||||
FHTTPMethod(r.Method),
|
||||
FHTTPTarget(r.URL.Path),
|
||||
FHTTPWroteBytes(r.ContentLength),
|
||||
)
|
||||
return With(l, Attributes(
|
||||
semconv.URLPath(r.URL.Path),
|
||||
semconv.UserAgentName(r.UserAgent()),
|
||||
semconv.HTTPRequestMethodKey.String(r.Method),
|
||||
semconv.HTTPRequestSizeKey.Int64(r.ContentLength),
|
||||
)...)
|
||||
}
|
||||
|
||||
@ -5,6 +5,7 @@ import (
|
||||
"time"
|
||||
|
||||
httplog "github.com/foomo/keel/net/http/log"
|
||||
semconv "go.opentelemetry.io/otel/semconv/v1.37.0"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
"go.uber.org/zap"
|
||||
|
||||
@ -98,8 +99,8 @@ func LoggerWithOptions(opts LoggerOptions) Middleware {
|
||||
|
||||
l = l.With(
|
||||
log.FDuration(time.Since(start)),
|
||||
log.FHTTPStatusCode(wr.StatusCode()),
|
||||
log.FHTTPWroteBytes(int64(wr.Size())),
|
||||
log.Attribute(semconv.HTTPResponseStatusCode(wr.StatusCode())),
|
||||
log.Attribute(semconv.HTTPResponseSize(wr.Size())),
|
||||
)
|
||||
|
||||
if labeler != nil {
|
||||
|
||||
@ -4,6 +4,7 @@ import (
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
semconv "go.opentelemetry.io/otel/semconv/v1.37.0"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
"go.uber.org/zap"
|
||||
|
||||
@ -86,10 +87,10 @@ func Logger(opts ...LoggerOption) RoundTripware {
|
||||
if err != nil {
|
||||
l = log.WithError(l, err)
|
||||
} else if resp != nil {
|
||||
l = log.With(l,
|
||||
log.FHTTPStatusCode(resp.StatusCode),
|
||||
log.FHTTPRequestContentLength(resp.ContentLength),
|
||||
)
|
||||
l = log.With(l, log.Attributes(
|
||||
semconv.HTTPResponseStatusCode(resp.StatusCode),
|
||||
semconv.HTTPResponseBodySizeKey.Int64(resp.ContentLength),
|
||||
)...)
|
||||
statusCode = resp.StatusCode
|
||||
}
|
||||
|
||||
|
||||
@ -7,6 +7,7 @@ import (
|
||||
|
||||
"github.com/nats-io/nats.go"
|
||||
"github.com/pkg/errors"
|
||||
semconv "go.opentelemetry.io/otel/semconv/v1.37.0"
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/foomo/keel/log"
|
||||
@ -122,7 +123,7 @@ func SubscriberWithUnmarshal(unmarshal UnmarshalFn) SubscriberOption {
|
||||
func New(l *zap.Logger, name, addr string, opts ...Option) (*Stream, error) {
|
||||
stream := &Stream{
|
||||
l: l.With(
|
||||
log.FMessagingSystem("jetstream"),
|
||||
log.Attribute(semconv.MessagingSystemKey.String("jetstream")),
|
||||
log.FName(name),
|
||||
),
|
||||
name: name,
|
||||
@ -294,7 +295,11 @@ func (s *Stream) connect() error {
|
||||
func (s *Stream) initNatsOptions() {
|
||||
natsOpts := append([]nats.Option{
|
||||
nats.ErrorHandler(func(conn *nats.Conn, subscription *nats.Subscription, err error) {
|
||||
s.l.Error("nats error", log.FError(err), log.FStreamQueue(subscription.Queue), log.FStreamSubject(subscription.Subject))
|
||||
s.l.Error("nats error",
|
||||
log.FError(err),
|
||||
log.Attribute(semconv.MessagingDestinationName(subscription.Queue)),
|
||||
log.Attribute(semconv.MessagingDestinationSubscriptionName(subscription.Subject)),
|
||||
)
|
||||
}),
|
||||
nats.ClosedHandler(func(conn *nats.Conn) {
|
||||
if err := conn.LastError(); err != nil {
|
||||
|
||||
22
semconv/http.go
Normal file
22
semconv/http.go
Normal file
@ -0,0 +1,22 @@
|
||||
package semconv
|
||||
|
||||
import (
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
)
|
||||
|
||||
const (
|
||||
// HTTPXRequestIDKey is the key for http.request.id.
|
||||
HTTPXRequestIDKey = attribute.Key("http.request.id")
|
||||
// HTTPXRequestRefererKey is the key for http.request.referer.
|
||||
HTTPXRequestRefererKey = attribute.Key("http.request.referer")
|
||||
)
|
||||
|
||||
// HTTPXRequestID returns a new attribute.KeyValue for http.request.id.
|
||||
func HTTPXRequestID(v string) attribute.KeyValue {
|
||||
return HTTPXRequestIDKey.String(v)
|
||||
}
|
||||
|
||||
// HTTPXRequestReferer returns a new attribute.KeyValue for http.request.referer.
|
||||
func HTTPXRequestReferer(v string) attribute.KeyValue {
|
||||
return HTTPXRequestRefererKey.String(v)
|
||||
}
|
||||
29
semconv/keel.go
Normal file
29
semconv/keel.go
Normal file
@ -0,0 +1,29 @@
|
||||
package semconv
|
||||
|
||||
import (
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
)
|
||||
|
||||
const (
|
||||
// KeelServiceTypeKey is the key for keel.service.type.
|
||||
KeelServiceTypeKey = attribute.Key("keel.service.type")
|
||||
// KeelServiceNameKey is the key for keel.service.name.
|
||||
KeelServiceNameKey = attribute.Key("keel.service.name")
|
||||
// KeelServiceInstKey is the key for keel.service.inst.
|
||||
KeelServiceInstKey = attribute.Key("keel.service.inst")
|
||||
)
|
||||
|
||||
// KeelServiceType returns a new attribute.KeyValue for keel.service.type.
|
||||
func KeelServiceType(v string) attribute.KeyValue {
|
||||
return KeelServiceTypeKey.String(v)
|
||||
}
|
||||
|
||||
// KeelServiceName returns a new attribute.KeyValue for keel.service.name.
|
||||
func KeelServiceName(v string) attribute.KeyValue {
|
||||
return KeelServiceNameKey.String(v)
|
||||
}
|
||||
|
||||
// KeelServiceInst returns a new attribute.KeyValue for keel.service.inst.
|
||||
func KeelServiceInst(v int) attribute.KeyValue {
|
||||
return KeelServiceInstKey.Int(v)
|
||||
}
|
||||
15
semconv/tracking.go
Normal file
15
semconv/tracking.go
Normal file
@ -0,0 +1,15 @@
|
||||
package semconv
|
||||
|
||||
import (
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
)
|
||||
|
||||
const (
|
||||
// TrackingIDKey is the key for tracking.id.
|
||||
TrackingIDKey = attribute.Key("tracking.id")
|
||||
)
|
||||
|
||||
// TrackingID returns a new attribute.KeyValue for tracking.id.
|
||||
func TrackingID(v string) attribute.KeyValue {
|
||||
return TrackingIDKey.String(v)
|
||||
}
|
||||
@ -6,6 +6,7 @@ import (
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
|
||||
"github.com/foomo/keel/semconv"
|
||||
"go.uber.org/zap"
|
||||
"golang.org/x/sync/errgroup"
|
||||
|
||||
@ -34,8 +35,8 @@ func NewGoRoutine(l *zap.Logger, name string, handler GoRoutineFn, opts ...GoRou
|
||||
}
|
||||
// enrich the log
|
||||
l = log.WithAttributes(l,
|
||||
log.KeelServiceTypeKey.String("goroutine"),
|
||||
log.KeelServiceNameKey.String(name),
|
||||
semconv.KeelServiceType("goroutine"),
|
||||
semconv.KeelServiceType(name),
|
||||
)
|
||||
|
||||
inst := &GoRoutine{
|
||||
@ -92,7 +93,7 @@ func (s *GoRoutine) Start(ctx context.Context) error {
|
||||
s.cancelLock.Unlock()
|
||||
|
||||
for i := range s.parallel {
|
||||
l := log.WithAttributes(s.l, log.KeelServiceInstKey.Int(i))
|
||||
l := log.WithAttributes(s.l, semconv.KeelServiceInst(i))
|
||||
s.wg.Go(func() error {
|
||||
return s.handler(ctx, l)
|
||||
})
|
||||
|
||||
@ -9,7 +9,9 @@ import (
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
keelsemconv "github.com/foomo/keel/semconv"
|
||||
"github.com/pkg/errors"
|
||||
semconv "go.opentelemetry.io/otel/semconv/v1.37.0"
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/foomo/keel/log"
|
||||
@ -34,8 +36,8 @@ func NewHTTP(l *zap.Logger, name, addr string, handler http.Handler, middlewares
|
||||
}
|
||||
// enrich the log
|
||||
l = log.WithAttributes(l,
|
||||
log.KeelServiceTypeKey.String("http"),
|
||||
log.KeelServiceNameKey.String(name),
|
||||
keelsemconv.KeelServiceType("http"),
|
||||
keelsemconv.KeelServiceName(name),
|
||||
)
|
||||
|
||||
return &HTTP{
|
||||
@ -87,7 +89,7 @@ func (s *HTTP) Start(ctx context.Context) error {
|
||||
ip = "0.0.0.0"
|
||||
}
|
||||
|
||||
fields = append(fields, log.FNetHostIP(ip), log.FNetHostPort(port))
|
||||
fields = append(fields, log.Attributes(semconv.ServerAddress(ip), semconv.ServerPortKey.String(port))...)
|
||||
}
|
||||
|
||||
s.l.Info("starting keel service", fields...)
|
||||
|
||||
@ -8,6 +8,7 @@ import (
|
||||
"github.com/foomo/keel/healthz"
|
||||
"github.com/foomo/keel/interfaces"
|
||||
"github.com/foomo/keel/log"
|
||||
semconv "go.opentelemetry.io/otel/semconv/v1.37.0"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
@ -30,7 +31,7 @@ func NewHealthz(l *zap.Logger, name, addr, path string, probes map[healthz.Type]
|
||||
|
||||
unavailable := func(l *zap.Logger, w http.ResponseWriter, r *http.Request, err error) {
|
||||
if err != nil {
|
||||
log.WithError(l, err).With(log.FHTTPTarget(r.RequestURI)).Debug("healthz probe failed")
|
||||
log.WithError(l, err).With(log.Attribute(semconv.URLFull(r.RequestURI))).Debug("healthz probe failed")
|
||||
http.Error(w, http.StatusText(http.StatusServiceUnavailable), http.StatusServiceUnavailable)
|
||||
}
|
||||
}
|
||||
|
||||
@ -16,6 +16,10 @@ type Context struct {
|
||||
context.Context
|
||||
}
|
||||
|
||||
func Ctx(ctx context.Context) Context {
|
||||
return Context{ctx}
|
||||
}
|
||||
|
||||
func (c Context) Log() *zap.Logger {
|
||||
return Log(c.Context)
|
||||
}
|
||||
@ -54,7 +58,3 @@ func (c Context) Profile(handler func(ctx Context), labels ...string) {
|
||||
handler(Ctx(ctx))
|
||||
})
|
||||
}
|
||||
|
||||
func Ctx(ctx context.Context) Context {
|
||||
return Context{ctx}
|
||||
}
|
||||
@ -22,7 +22,7 @@ func NewResource(ctx context.Context) (*resource.Resource, error) {
|
||||
semconv.VCSRefHeadNameKey: {"GIT_BRANCH", "OTEL_VCS_HEAD_NAME"},
|
||||
semconv.VCSRefHeadRevisionKey: {"GIT_COMMIT", "GIT_COMMIT_HASH", "OTEL_VCS_HEAD_REVSION"},
|
||||
semconv.VCSRefHeadTypeKey: {"GIT_TYPE", "OTEL_VCS_HEAD_TYPE"},
|
||||
"vcs_root_path": {"OTEL_VCS_ROOT_PATH"},
|
||||
"vcs_root_path": {"REPO_PATH", "REPOSITORY_PATH", "GIT_REPOSITORY_PATH", "OTEL_VCS_ROOT_PATH"},
|
||||
}
|
||||
for k, keys := range envs {
|
||||
for _, key := range keys {
|
||||
|
||||
@ -5,6 +5,7 @@ import (
|
||||
|
||||
httplog "github.com/foomo/keel/net/http/log"
|
||||
"github.com/pkg/errors"
|
||||
semconv "go.opentelemetry.io/otel/semconv/v1.37.0"
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/foomo/keel/log"
|
||||
@ -48,7 +49,7 @@ func ServerError(l *zap.Logger, w http.ResponseWriter, r *http.Request, code int
|
||||
} else {
|
||||
l = log.WithError(l, err)
|
||||
l = log.WithHTTPRequest(l, r)
|
||||
l.Error("http server error", log.FHTTPStatusCode(code))
|
||||
l.Error("http server error", log.Attribute(semconv.HTTPResponseStatusCode(code)))
|
||||
}
|
||||
// w.Header().Set(keelhttp.HeaderXError, err.Error()) TODO make configurable with better value
|
||||
http.Error(w, http.StatusText(code), code)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user