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"
|
"net/http/httptest"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
semconv "go.opentelemetry.io/otel/semconv/v1.37.0"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
|
|
||||||
"github.com/foomo/keel/log"
|
"github.com/foomo/keel/log"
|
||||||
@ -58,7 +59,7 @@ func (s *ServiceHTTP) Start(ctx context.Context) error {
|
|||||||
ip = "0.0.0.0"
|
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...)
|
s.l.Info("starting http test service", fields...)
|
||||||
|
|||||||
@ -18,22 +18,22 @@ const (
|
|||||||
JSONKey = "json"
|
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 {
|
func FNum(num int) zap.Field {
|
||||||
return zap.Int(NumKey, num)
|
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 {
|
func FName(name string) zap.Field {
|
||||||
return zap.String(NameKey, name)
|
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 {
|
func FValue(value interface{}) zap.Field {
|
||||||
return zap.String(ValueKey, fmt.Sprintf("%v", value))
|
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 {
|
func FJSON(v interface{}) zap.Field {
|
||||||
if out, err := json.Marshal(v); err != nil {
|
if out, err := json.Marshal(v); err != nil {
|
||||||
return zap.String(JSONKey+"_error", err.Error())
|
return zap.String(JSONKey+"_error", err.Error())
|
||||||
|
|||||||
@ -5,24 +5,32 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
// Deprecated: use semconv messaging attributes instead.
|
||||||
CodeInstanceKey = "code_instance"
|
CodeInstanceKey = "code_instance"
|
||||||
CodePackageKey = "code_package"
|
// Deprecated: use semconv messaging attributes instead.
|
||||||
CodeMethodKey = "code_method"
|
CodePackageKey = "code_package"
|
||||||
CodeLineKey = "code_line"
|
// 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 {
|
func FCodeInstance(v string) zap.Field {
|
||||||
return zap.String(CodeInstanceKey, v)
|
return zap.String(CodeInstanceKey, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Deprecated: use semconv messaging attributes instead.
|
||||||
func FCodePackage(v string) zap.Field {
|
func FCodePackage(v string) zap.Field {
|
||||||
return zap.String(CodePackageKey, v)
|
return zap.String(CodePackageKey, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Deprecated: use semconv messaging attributes instead.
|
||||||
func FCodeMethod(v string) zap.Field {
|
func FCodeMethod(v string) zap.Field {
|
||||||
return zap.String(CodeMethodKey, v)
|
return zap.String(CodeMethodKey, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Deprecated: use semconv messaging attributes instead.
|
||||||
func FCodeLine(v int) zap.Field {
|
func FCodeLine(v int) zap.Field {
|
||||||
return zap.Int(CodeLineKey, v)
|
return zap.Int(CodeLineKey, v)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,28 +7,37 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
DurationKey = "duration"
|
// DurationKey - generic duration attribute
|
||||||
DurationSecKey = "duration_sec"
|
DurationKey = "duration"
|
||||||
DurationMinKey = "duration_min"
|
// DurationSecKey - duration in seconds
|
||||||
|
DurationSecKey = "duration_sec"
|
||||||
|
// DurationMinKey - duration in minutes
|
||||||
|
DurationMinKey = "duration_min"
|
||||||
|
// DurationHourKey - duration in hours
|
||||||
DurationHourKey = "duration_hour"
|
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 {
|
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 {
|
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 {
|
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 {
|
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 {
|
func FDurationFn() func() zap.Field {
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
|
|
||||||
|
|||||||
@ -5,110 +5,109 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// HTTPServerNameKey represents the name of the service handling the request
|
// Deprecated: use semconv messaging attributes instead.
|
||||||
HTTPServerNameKey = "http_server_name"
|
HTTPServerNameKey = "http_server_name"
|
||||||
|
// Deprecated: use semconv messaging attributes instead.
|
||||||
// HTTPMethodKey represents the HTTP request method.
|
|
||||||
HTTPMethodKey = "http_method"
|
HTTPMethodKey = "http_method"
|
||||||
|
// Deprecated: use semconv messaging attributes instead.
|
||||||
// HTTPTargetKey represents the full request target as passed in a HTTP
|
|
||||||
// request line or equivalent, e.g. "/path/12314/?q=ddds#123".
|
|
||||||
HTTPTargetKey = "http_target"
|
HTTPTargetKey = "http_target"
|
||||||
|
// Deprecated: use semconv messaging attributes instead.
|
||||||
// HTTPHostKey represents the value of the HTTP host header.
|
|
||||||
HTTPHostKey = "http_host"
|
HTTPHostKey = "http_host"
|
||||||
|
// Deprecated: use semconv messaging attributes instead.
|
||||||
// HTTPStatusCodeKey represents the HTTP response status code.
|
|
||||||
HTTPStatusCodeKey = "http_status_code"
|
HTTPStatusCodeKey = "http_status_code"
|
||||||
|
// Deprecated: use semconv messaging attributes instead.
|
||||||
// HTTPUserAgentKey represents the Value of the HTTP User-Agent header sent by the client.
|
|
||||||
HTTPUserAgentKey = "http_user_agent"
|
HTTPUserAgentKey = "http_user_agent"
|
||||||
|
// Deprecated: use semconv messaging attributes instead.
|
||||||
// HTTPClientIPKey represents the IP address of the original client behind all proxies,
|
|
||||||
// if known (e.g. from X-Forwarded-For).
|
|
||||||
HTTPClientIPKey = "http_client_ip"
|
HTTPClientIPKey = "http_client_ip"
|
||||||
|
// Deprecated: use semconv messaging attributes instead.
|
||||||
// HTTPRequestContentLengthKey represents the size of the request payload body in bytes.
|
|
||||||
HTTPRequestContentLengthKey = "http_read_bytes"
|
HTTPRequestContentLengthKey = "http_read_bytes"
|
||||||
|
// Deprecated: use semconv messaging attributes instead.
|
||||||
// HTTPWroteBytesKey represents the size of the response payload body in bytes.
|
|
||||||
HTTPWroteBytesKey = "http_wrote_bytes" // #nosec
|
HTTPWroteBytesKey = "http_wrote_bytes" // #nosec
|
||||||
|
// Deprecated: use semconv messaging attributes instead.
|
||||||
// HTTPSchemeKey represents the URI scheme identifying the used protocol.
|
|
||||||
HTTPSchemeKey = "http_scheme"
|
HTTPSchemeKey = "http_scheme"
|
||||||
|
// Deprecated: use semconv messaging attributes instead.
|
||||||
// HTTPFlavorKey represents the Kind of HTTP protocol used.
|
|
||||||
HTTPFlavorKey = "http_flavor"
|
HTTPFlavorKey = "http_flavor"
|
||||||
|
// Deprecated: use semconv messaging attributes instead.
|
||||||
// HTTPRequestIDKey represents the HTTP request id if known (e.g. from X-Request-ID).
|
|
||||||
HTTPRequestIDKey = "http_request_id"
|
HTTPRequestIDKey = "http_request_id"
|
||||||
|
// Deprecated: use semconv messaging attributes instead.
|
||||||
// HTTPSessionIDKey represents the HTTP session id if known (e.g. from X-Session-ID).
|
|
||||||
HTTPSessionIDKey = "http_session_id"
|
HTTPSessionIDKey = "http_session_id"
|
||||||
|
// Deprecated: use semconv messaging attributes instead.
|
||||||
// HTTPTrackingIDKey represents the HTTP tracking id if known (e.g. from X-Tracking-ID).
|
|
||||||
HTTPTrackingIDKey = "http_tracking_id"
|
HTTPTrackingIDKey = "http_tracking_id"
|
||||||
|
// Deprecated: use semconv messaging attributes instead.
|
||||||
// HTTPRefererKey identifies the address of the web page (i.e., the URI or IRI), from which the resource has been requested.
|
|
||||||
HTTPRefererKey = "http_referer"
|
HTTPRefererKey = "http_referer"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Deprecated: use semconv messaging attributes instead.
|
||||||
func FHTTPServerName(id string) zap.Field {
|
func FHTTPServerName(id string) zap.Field {
|
||||||
return zap.String(HTTPServerNameKey, id)
|
return zap.String(HTTPServerNameKey, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Deprecated: use semconv messaging attributes instead.
|
||||||
func FHTTPRequestID(id string) zap.Field {
|
func FHTTPRequestID(id string) zap.Field {
|
||||||
return zap.String(HTTPRequestIDKey, id)
|
return zap.String(HTTPRequestIDKey, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Deprecated: use semconv messaging attributes instead.
|
||||||
func FHTTPSessionID(id string) zap.Field {
|
func FHTTPSessionID(id string) zap.Field {
|
||||||
return zap.String(HTTPSessionIDKey, id)
|
return zap.String(HTTPSessionIDKey, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Deprecated: use semconv messaging attributes instead.
|
||||||
func FHTTPTrackingID(id string) zap.Field {
|
func FHTTPTrackingID(id string) zap.Field {
|
||||||
return zap.String(HTTPTrackingIDKey, id)
|
return zap.String(HTTPTrackingIDKey, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Deprecated: use semconv messaging attributes instead.
|
||||||
func FHTTPRequestContentLength(bytes int64) zap.Field {
|
func FHTTPRequestContentLength(bytes int64) zap.Field {
|
||||||
return zap.Int64(HTTPRequestContentLengthKey, bytes)
|
return zap.Int64(HTTPRequestContentLengthKey, bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Deprecated: use semconv messaging attributes instead.
|
||||||
func FHTTPWroteBytes(bytes int64) zap.Field {
|
func FHTTPWroteBytes(bytes int64) zap.Field {
|
||||||
return zap.Int64(HTTPWroteBytesKey, bytes)
|
return zap.Int64(HTTPWroteBytesKey, bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Deprecated: use semconv messaging attributes instead.
|
||||||
func FHTTPStatusCode(status int) zap.Field {
|
func FHTTPStatusCode(status int) zap.Field {
|
||||||
return zap.Int(HTTPStatusCodeKey, status)
|
return zap.Int(HTTPStatusCodeKey, status)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Deprecated: use semconv messaging attributes instead.
|
||||||
func FHTTPTarget(target string) zap.Field {
|
func FHTTPTarget(target string) zap.Field {
|
||||||
return zap.String(HTTPTargetKey, target)
|
return zap.String(HTTPTargetKey, target)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Deprecated: use semconv messaging attributes instead.
|
||||||
func FHTTPClientIP(clientIP string) zap.Field {
|
func FHTTPClientIP(clientIP string) zap.Field {
|
||||||
return zap.String(HTTPClientIPKey, clientIP)
|
return zap.String(HTTPClientIPKey, clientIP)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Deprecated: use semconv messaging attributes instead.
|
||||||
func FHTTPFlavor(flavor string) zap.Field {
|
func FHTTPFlavor(flavor string) zap.Field {
|
||||||
return zap.String(HTTPFlavorKey, flavor)
|
return zap.String(HTTPFlavorKey, flavor)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Deprecated: use semconv messaging attributes instead.
|
||||||
func FHTTPScheme(scheme string) zap.Field {
|
func FHTTPScheme(scheme string) zap.Field {
|
||||||
return zap.String(HTTPSchemeKey, scheme)
|
return zap.String(HTTPSchemeKey, scheme)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Deprecated: use semconv messaging attributes instead.
|
||||||
func FHTTPUserAgent(userAgent string) zap.Field {
|
func FHTTPUserAgent(userAgent string) zap.Field {
|
||||||
return zap.String(HTTPUserAgentKey, userAgent)
|
return zap.String(HTTPUserAgentKey, userAgent)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Deprecated: use semconv messaging attributes instead.
|
||||||
func FHTTPReferer(host string) zap.Field {
|
func FHTTPReferer(host string) zap.Field {
|
||||||
return zap.String(HTTPRefererKey, host)
|
return zap.String(HTTPRefererKey, host)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Deprecated: use semconv messaging attributes instead.
|
||||||
func FHTTPHost(host string) zap.Field {
|
func FHTTPHost(host string) zap.Field {
|
||||||
return zap.String(HTTPHostKey, host)
|
return zap.String(HTTPHostKey, host)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Deprecated: use semconv messaging attributes instead.
|
||||||
func FHTTPMethod(name string) zap.Field {
|
func FHTTPMethod(name string) zap.Field {
|
||||||
return zap.String(HTTPMethodKey, name)
|
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
|
package log
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
semconv "go.opentelemetry.io/otel/semconv/v1.37.0"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
MessagingSystemKey = "messaging_system"
|
// Deprecated: use semconv messaging attributes instead.
|
||||||
MessagingDestinationKey = "messaging_destination"
|
MessagingSystemKey = "messaging_system"
|
||||||
MessagingDestinationKindKey = "messaging_destination_kind"
|
// Deprecated: use semconv messaging attributes instead.
|
||||||
MessagingProtocolKey = "messaging_protocol"
|
MessagingDestinationKey = "messaging_destination"
|
||||||
MessagingProtocolVersionKey = "messaging_protocol_version"
|
// Deprecated: use semconv messaging attributes instead.
|
||||||
MessagingURLKey = "messaging_url"
|
MessagingDestinationKindKey = "messaging_destination_kind"
|
||||||
MessagingMessageIDKey = "messaging_message_id"
|
// Deprecated: use semconv messaging attributes instead.
|
||||||
MessagingConversationIDKey = "messaging_conversation_id"
|
MessagingProtocolKey = "messaging_protocol"
|
||||||
MessagingMessagePayloadSizeBytesKey = "messaging_message_payload_size_bytes"
|
// 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"
|
MessagingMessagePayloadCompressedSizeBytesKey = "messaging_message_payload_compressed_size_bytes"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Deprecated: use semconv messaging attributes instead.
|
||||||
type MessagingDestinationKind string
|
type MessagingDestinationKind string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
// Deprecated: use semconv messaging attributes instead.
|
||||||
MessagingDestinationKindQueue MessagingDestinationKind = "queue"
|
MessagingDestinationKindQueue MessagingDestinationKind = "queue"
|
||||||
|
// Deprecated: use semconv messaging attributes instead.
|
||||||
MessagingDestinationKindTopic MessagingDestinationKind = "topic"
|
MessagingDestinationKindTopic MessagingDestinationKind = "topic"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Deprecated: use semconv messaging attributes instead.
|
||||||
func FMessagingSystem(value string) zap.Field {
|
func FMessagingSystem(value string) zap.Field {
|
||||||
return zap.String(MessagingSystemKey, value)
|
return zap.String(MessagingSystemKey, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Deprecated: use semconv.MessagingDestinationName instead.
|
||||||
func FMessagingDestination(value string) zap.Field {
|
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 {
|
func FMessagingDestinationKind(value MessagingDestinationKind) zap.Field {
|
||||||
return zap.String(MessagingDestinationKindKey, string(value))
|
return zap.String(MessagingDestinationKindKey, string(value))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Deprecated: use semconv messaging attributes instead.
|
||||||
func FMessagingProtocol(value string) zap.Field {
|
func FMessagingProtocol(value string) zap.Field {
|
||||||
return zap.String(MessagingProtocolKey, value)
|
return zap.String(MessagingProtocolKey, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Deprecated: use semconv messaging attributes instead.
|
||||||
func FMessagingProtocolVersion(value string) zap.Field {
|
func FMessagingProtocolVersion(value string) zap.Field {
|
||||||
return zap.String(MessagingProtocolVersionKey, value)
|
return zap.String(MessagingProtocolVersionKey, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Deprecated: use semconv messaging attributes instead.
|
||||||
func FMessagingURL(value string) zap.Field {
|
func FMessagingURL(value string) zap.Field {
|
||||||
return zap.String(MessagingURLKey, value)
|
return zap.String(MessagingURLKey, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Deprecated: use semconv.MessagingMessageID instead.
|
||||||
func FMessagingMessageID(value string) zap.Field {
|
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 {
|
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 {
|
func FMessagingMessagePayloadSizeBytes(value string) zap.Field {
|
||||||
return zap.String(MessagingMessagePayloadSizeBytesKey, value)
|
return zap.String(MessagingMessagePayloadSizeBytesKey, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Deprecated: use semconv messaging attributes instead.
|
||||||
func FMessagingMessagePayloadCompressedSizeBytes(value string) zap.Field {
|
func FMessagingMessagePayloadCompressedSizeBytes(value string) zap.Field {
|
||||||
return zap.String(MessagingMessagePayloadCompressedSizeBytesKey, value)
|
return zap.String(MessagingMessagePayloadCompressedSizeBytesKey, value)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,21 +1,23 @@
|
|||||||
package log
|
package log
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
semconv "go.opentelemetry.io/otel/semconv/v1.37.0"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
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"
|
NetHostIPKey = "net_host_ip"
|
||||||
|
// Deprecated: use semconv messaging attributes instead.
|
||||||
// NetHostPortKey represents the local host port.
|
|
||||||
NetHostPortKey = "net_host_port"
|
NetHostPortKey = "net_host_port"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Deprecated: use semconv messaging attributes instead.
|
||||||
func FNetHostIP(ip string) zap.Field {
|
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 {
|
func FNetHostPort(port string) zap.Field {
|
||||||
return zap.String(NetHostPortKey, port)
|
return zap.String(NetHostPortKey, port)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,58 +5,53 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// PeerServiceKey represents the ServiceNameKey name of the remote service.
|
// Deprecated: use semconv messaging attributes instead.
|
||||||
// Should equal the actual `service.name` resource attribute of the remote service, if any.
|
|
||||||
PeerServiceKey = "peer_service"
|
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 {
|
func FPeerService(name string) zap.Field {
|
||||||
return zap.String(PeerServiceKey, name)
|
return zap.String(PeerServiceKey, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
// Deprecated: use semconv messaging attributes instead.
|
||||||
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"
|
|
||||||
)
|
|
||||||
|
|
||||||
func FServiceType(name string) zap.Field {
|
func FServiceType(name string) zap.Field {
|
||||||
return zap.String(ServiceTypeKey, name)
|
return zap.String(ServiceTypeKey, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Deprecated: use semconv messaging attributes instead.
|
||||||
func FServiceName(name string) zap.Field {
|
func FServiceName(name string) zap.Field {
|
||||||
return zap.String(ServiceNameKey, name)
|
return zap.String(ServiceNameKey, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Deprecated: use semconv messaging attributes instead.
|
||||||
func FServiceNamespace(namespace string) zap.Field {
|
func FServiceNamespace(namespace string) zap.Field {
|
||||||
return zap.String(ServiceNamespaceKey, namespace)
|
return zap.String(ServiceNamespaceKey, namespace)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Deprecated: use semconv messaging attributes instead.
|
||||||
func FServiceInstanceID(id string) zap.Field {
|
func FServiceInstanceID(id string) zap.Field {
|
||||||
return zap.String(ServiceInstanceIDKey, id)
|
return zap.String(ServiceInstanceIDKey, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Deprecated: use semconv messaging attributes instead.
|
||||||
func FServiceVersion(version string) zap.Field {
|
func FServiceVersion(version string) zap.Field {
|
||||||
return zap.String(ServiceVersionKey, version)
|
return zap.String(ServiceVersionKey, version)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Deprecated: use semconv messaging attributes instead.
|
||||||
func FServiceMethod(method string) zap.Field {
|
func FServiceMethod(method string) zap.Field {
|
||||||
return zap.String(ServiceMethodKey, method)
|
return zap.String(ServiceMethodKey, method)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,14 +5,18 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
StreamQueueKey = "queue"
|
// Deprecated: use semconv messaging attributes instead.
|
||||||
|
StreamQueueKey = "queue"
|
||||||
|
// Deprecated: use semconv messaging attributes instead.
|
||||||
StreamSubjectKey = "subject"
|
StreamSubjectKey = "subject"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Deprecated: use semconv messaging attributes instead.
|
||||||
func FStreamQueue(queue string) zap.Field {
|
func FStreamQueue(queue string) zap.Field {
|
||||||
return zap.String(StreamQueueKey, queue)
|
return zap.String(StreamQueueKey, queue)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Deprecated: use semconv messaging attributes instead.
|
||||||
func FStreamSubject(name string) zap.Field {
|
func FStreamSubject(name string) zap.Field {
|
||||||
return zap.String(StreamSubjectKey, name)
|
return zap.String(StreamSubjectKey, name)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,6 +2,7 @@ package log
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
semconv "go.opentelemetry.io/otel/semconv/v1.37.0"
|
semconv "go.opentelemetry.io/otel/semconv/v1.37.0"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
@ -41,8 +42,8 @@ func NewLogger(level, encoding string) *zap.Logger {
|
|||||||
config.EncoderConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder
|
config.EncoderConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder
|
||||||
}
|
}
|
||||||
|
|
||||||
config.EncoderConfig.CallerKey = string(semconv.CodeFilePathKey)
|
config.EncoderConfig.CallerKey = strings.ReplaceAll(string(semconv.CodeFilePathKey), ".", "_")
|
||||||
config.EncoderConfig.StacktraceKey = string(semconv.CodeStacktraceKey)
|
config.EncoderConfig.StacktraceKey = strings.ReplaceAll(string(semconv.CodeStacktraceKey), ".", "_")
|
||||||
config.EncoderConfig.EncodeCaller = func(caller zapcore.EntryCaller, encoder zapcore.PrimitiveArrayEncoder) {
|
config.EncoderConfig.EncodeCaller = func(caller zapcore.EntryCaller, encoder zapcore.PrimitiveArrayEncoder) {
|
||||||
encoder.AppendString(caller.File)
|
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"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
keelsemconv "github.com/foomo/keel/semconv"
|
||||||
"go.opentelemetry.io/otel/attribute"
|
"go.opentelemetry.io/otel/attribute"
|
||||||
|
semconv "go.opentelemetry.io/otel/semconv/v1.37.0"
|
||||||
"go.opentelemetry.io/otel/trace"
|
"go.opentelemetry.io/otel/trace"
|
||||||
"go.uber.org/zap"
|
"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 {
|
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 {
|
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 {
|
func WithHTTPFlavor(l *zap.Logger, r *http.Request) *zap.Logger {
|
||||||
switch r.ProtoMajor {
|
return With(l, Attributes(semconv.NetworkProtocolName("HTTP"), semconv.NetworkProtocolVersion(fmt.Sprintf("%d.%d", r.ProtoMajor, r.ProtoMinor)))...)
|
||||||
case 1:
|
|
||||||
return With(l, FHTTPFlavor(fmt.Sprintf("1.%d", r.ProtoMinor)))
|
|
||||||
case 2:
|
|
||||||
return With(l, FHTTPFlavor("2"))
|
|
||||||
default:
|
|
||||||
return l
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func WithHTTPScheme(l *zap.Logger, r *http.Request) *zap.Logger {
|
func WithHTTPScheme(l *zap.Logger, r *http.Request) *zap.Logger {
|
||||||
if r.TLS != nil {
|
if r.TLS != nil {
|
||||||
return With(l, FHTTPScheme("https"))
|
return With(l, Attribute(semconv.URLScheme("https")))
|
||||||
} else {
|
} else {
|
||||||
return With(l, FHTTPScheme("http"))
|
return With(l, Attribute(semconv.URLScheme("http")))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func WithHTTPSessionID(l *zap.Logger, r *http.Request) *zap.Logger {
|
func WithHTTPSessionID(l *zap.Logger, r *http.Request) *zap.Logger {
|
||||||
if id := r.Header.Get("X-Session-Id"); id != "" {
|
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 != "" {
|
} else if id, ok := keelhttpcontext.GetSessionID(r.Context()); ok && id != "" {
|
||||||
return With(l, FHTTPSessionID(id))
|
return With(l, Attribute(semconv.SessionID(id)))
|
||||||
} else {
|
} else {
|
||||||
return l
|
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 {
|
func WithHTTPRequestID(l *zap.Logger, r *http.Request) *zap.Logger {
|
||||||
if id := r.Header.Get("X-Request-Id"); id != "" {
|
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 != "" {
|
} else if id, ok := keelhttpcontext.GetRequestID(r.Context()); ok && id != "" {
|
||||||
return With(l, FHTTPRequestID(id))
|
return With(l, Attribute(keelsemconv.HTTPXRequestID(id)))
|
||||||
} else {
|
} else {
|
||||||
return l
|
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 {
|
func WithHTTPReferer(l *zap.Logger, r *http.Request) *zap.Logger {
|
||||||
if value := r.Header.Get("X-Referer"); value != "" {
|
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 != "" {
|
} else if value := r.Referer(); value != "" {
|
||||||
return With(l, FHTTPReferer(value))
|
return With(l, Attribute(keelsemconv.HTTPXRequestReferer(value)))
|
||||||
} else {
|
} else {
|
||||||
return l
|
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 {
|
func WithHTTPHost(l *zap.Logger, r *http.Request) *zap.Logger {
|
||||||
if value := r.Header.Get("X-Forwarded-Host"); value != "" {
|
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() {
|
} else if !r.URL.IsAbs() {
|
||||||
return With(l, FHTTPHost(r.Host))
|
return With(l, Attribute(semconv.HostName(r.Host)))
|
||||||
} else {
|
} 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 {
|
func WithHTTPTrackingID(l *zap.Logger, r *http.Request) *zap.Logger {
|
||||||
if id := r.Header.Get("X-Tracking-Id"); id != "" {
|
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 != "" {
|
} else if id, ok := keelhttpcontext.GetTrackingID(r.Context()); ok && id != "" {
|
||||||
return With(l, FHTTPTrackingID(id))
|
return With(l, Attribute(keelsemconv.TrackingID(id)))
|
||||||
} else {
|
} else {
|
||||||
return l
|
return l
|
||||||
}
|
}
|
||||||
@ -142,7 +137,7 @@ func WithHTTPClientIP(l *zap.Logger, r *http.Request) *zap.Logger {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if clientIP != "" {
|
if clientIP != "" {
|
||||||
return With(l, FHTTPClientIP(clientIP))
|
return With(l, Attribute(semconv.ClientAddress(clientIP)))
|
||||||
}
|
}
|
||||||
|
|
||||||
return l
|
return l
|
||||||
@ -159,12 +154,12 @@ func WithHTTPRequest(l *zap.Logger, r *http.Request) *zap.Logger {
|
|||||||
l = WithHTTPClientIP(l, r)
|
l = WithHTTPClientIP(l, r)
|
||||||
l = WithTraceID(l, r.Context())
|
l = WithTraceID(l, r.Context())
|
||||||
|
|
||||||
return With(l,
|
return With(l, Attributes(
|
||||||
FHTTPMethod(r.Method),
|
semconv.URLPath(r.URL.Path),
|
||||||
FHTTPTarget(r.RequestURI),
|
semconv.UserAgentName(r.UserAgent()),
|
||||||
FHTTPUserAgent(r.UserAgent()),
|
semconv.HTTPRequestMethodKey.String(r.Method),
|
||||||
FHTTPRequestContentLength(r.ContentLength),
|
semconv.HTTPRequestSizeKey.Int64(r.ContentLength),
|
||||||
)
|
)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func WithHTTPRequestOut(l *zap.Logger, r *http.Request) *zap.Logger {
|
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 = WithHTTPFlavor(l, r)
|
||||||
l = WithTraceID(l, r.Context())
|
l = WithTraceID(l, r.Context())
|
||||||
|
|
||||||
return With(l,
|
return With(l, Attributes(
|
||||||
FHTTPMethod(r.Method),
|
semconv.URLPath(r.URL.Path),
|
||||||
FHTTPTarget(r.URL.Path),
|
semconv.UserAgentName(r.UserAgent()),
|
||||||
FHTTPWroteBytes(r.ContentLength),
|
semconv.HTTPRequestMethodKey.String(r.Method),
|
||||||
)
|
semconv.HTTPRequestSizeKey.Int64(r.ContentLength),
|
||||||
|
)...)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,6 +5,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
httplog "github.com/foomo/keel/net/http/log"
|
httplog "github.com/foomo/keel/net/http/log"
|
||||||
|
semconv "go.opentelemetry.io/otel/semconv/v1.37.0"
|
||||||
"go.opentelemetry.io/otel/trace"
|
"go.opentelemetry.io/otel/trace"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
|
|
||||||
@ -98,8 +99,8 @@ func LoggerWithOptions(opts LoggerOptions) Middleware {
|
|||||||
|
|
||||||
l = l.With(
|
l = l.With(
|
||||||
log.FDuration(time.Since(start)),
|
log.FDuration(time.Since(start)),
|
||||||
log.FHTTPStatusCode(wr.StatusCode()),
|
log.Attribute(semconv.HTTPResponseStatusCode(wr.StatusCode())),
|
||||||
log.FHTTPWroteBytes(int64(wr.Size())),
|
log.Attribute(semconv.HTTPResponseSize(wr.Size())),
|
||||||
)
|
)
|
||||||
|
|
||||||
if labeler != nil {
|
if labeler != nil {
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
semconv "go.opentelemetry.io/otel/semconv/v1.37.0"
|
||||||
"go.opentelemetry.io/otel/trace"
|
"go.opentelemetry.io/otel/trace"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
|
|
||||||
@ -86,10 +87,10 @@ func Logger(opts ...LoggerOption) RoundTripware {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
l = log.WithError(l, err)
|
l = log.WithError(l, err)
|
||||||
} else if resp != nil {
|
} else if resp != nil {
|
||||||
l = log.With(l,
|
l = log.With(l, log.Attributes(
|
||||||
log.FHTTPStatusCode(resp.StatusCode),
|
semconv.HTTPResponseStatusCode(resp.StatusCode),
|
||||||
log.FHTTPRequestContentLength(resp.ContentLength),
|
semconv.HTTPResponseBodySizeKey.Int64(resp.ContentLength),
|
||||||
)
|
)...)
|
||||||
statusCode = resp.StatusCode
|
statusCode = resp.StatusCode
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import (
|
|||||||
|
|
||||||
"github.com/nats-io/nats.go"
|
"github.com/nats-io/nats.go"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
semconv "go.opentelemetry.io/otel/semconv/v1.37.0"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
|
|
||||||
"github.com/foomo/keel/log"
|
"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) {
|
func New(l *zap.Logger, name, addr string, opts ...Option) (*Stream, error) {
|
||||||
stream := &Stream{
|
stream := &Stream{
|
||||||
l: l.With(
|
l: l.With(
|
||||||
log.FMessagingSystem("jetstream"),
|
log.Attribute(semconv.MessagingSystemKey.String("jetstream")),
|
||||||
log.FName(name),
|
log.FName(name),
|
||||||
),
|
),
|
||||||
name: name,
|
name: name,
|
||||||
@ -294,7 +295,11 @@ func (s *Stream) connect() error {
|
|||||||
func (s *Stream) initNatsOptions() {
|
func (s *Stream) initNatsOptions() {
|
||||||
natsOpts := append([]nats.Option{
|
natsOpts := append([]nats.Option{
|
||||||
nats.ErrorHandler(func(conn *nats.Conn, subscription *nats.Subscription, err error) {
|
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) {
|
nats.ClosedHandler(func(conn *nats.Conn) {
|
||||||
if err := conn.LastError(); err != nil {
|
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"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
|
||||||
|
"github.com/foomo/keel/semconv"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
"golang.org/x/sync/errgroup"
|
"golang.org/x/sync/errgroup"
|
||||||
|
|
||||||
@ -34,8 +35,8 @@ func NewGoRoutine(l *zap.Logger, name string, handler GoRoutineFn, opts ...GoRou
|
|||||||
}
|
}
|
||||||
// enrich the log
|
// enrich the log
|
||||||
l = log.WithAttributes(l,
|
l = log.WithAttributes(l,
|
||||||
log.KeelServiceTypeKey.String("goroutine"),
|
semconv.KeelServiceType("goroutine"),
|
||||||
log.KeelServiceNameKey.String(name),
|
semconv.KeelServiceType(name),
|
||||||
)
|
)
|
||||||
|
|
||||||
inst := &GoRoutine{
|
inst := &GoRoutine{
|
||||||
@ -92,7 +93,7 @@ func (s *GoRoutine) Start(ctx context.Context) error {
|
|||||||
s.cancelLock.Unlock()
|
s.cancelLock.Unlock()
|
||||||
|
|
||||||
for i := range s.parallel {
|
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 {
|
s.wg.Go(func() error {
|
||||||
return s.handler(ctx, l)
|
return s.handler(ctx, l)
|
||||||
})
|
})
|
||||||
|
|||||||
@ -9,7 +9,9 @@ import (
|
|||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
keelsemconv "github.com/foomo/keel/semconv"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
semconv "go.opentelemetry.io/otel/semconv/v1.37.0"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
|
|
||||||
"github.com/foomo/keel/log"
|
"github.com/foomo/keel/log"
|
||||||
@ -34,8 +36,8 @@ func NewHTTP(l *zap.Logger, name, addr string, handler http.Handler, middlewares
|
|||||||
}
|
}
|
||||||
// enrich the log
|
// enrich the log
|
||||||
l = log.WithAttributes(l,
|
l = log.WithAttributes(l,
|
||||||
log.KeelServiceTypeKey.String("http"),
|
keelsemconv.KeelServiceType("http"),
|
||||||
log.KeelServiceNameKey.String(name),
|
keelsemconv.KeelServiceName(name),
|
||||||
)
|
)
|
||||||
|
|
||||||
return &HTTP{
|
return &HTTP{
|
||||||
@ -87,7 +89,7 @@ func (s *HTTP) Start(ctx context.Context) error {
|
|||||||
ip = "0.0.0.0"
|
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...)
|
s.l.Info("starting keel service", fields...)
|
||||||
|
|||||||
@ -8,6 +8,7 @@ import (
|
|||||||
"github.com/foomo/keel/healthz"
|
"github.com/foomo/keel/healthz"
|
||||||
"github.com/foomo/keel/interfaces"
|
"github.com/foomo/keel/interfaces"
|
||||||
"github.com/foomo/keel/log"
|
"github.com/foomo/keel/log"
|
||||||
|
semconv "go.opentelemetry.io/otel/semconv/v1.37.0"
|
||||||
"go.uber.org/zap"
|
"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) {
|
unavailable := func(l *zap.Logger, w http.ResponseWriter, r *http.Request, err error) {
|
||||||
if err != nil {
|
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)
|
http.Error(w, http.StatusText(http.StatusServiceUnavailable), http.StatusServiceUnavailable)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,6 +16,10 @@ type Context struct {
|
|||||||
context.Context
|
context.Context
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Ctx(ctx context.Context) Context {
|
||||||
|
return Context{ctx}
|
||||||
|
}
|
||||||
|
|
||||||
func (c Context) Log() *zap.Logger {
|
func (c Context) Log() *zap.Logger {
|
||||||
return Log(c.Context)
|
return Log(c.Context)
|
||||||
}
|
}
|
||||||
@ -54,7 +58,3 @@ func (c Context) Profile(handler func(ctx Context), labels ...string) {
|
|||||||
handler(Ctx(ctx))
|
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.VCSRefHeadNameKey: {"GIT_BRANCH", "OTEL_VCS_HEAD_NAME"},
|
||||||
semconv.VCSRefHeadRevisionKey: {"GIT_COMMIT", "GIT_COMMIT_HASH", "OTEL_VCS_HEAD_REVSION"},
|
semconv.VCSRefHeadRevisionKey: {"GIT_COMMIT", "GIT_COMMIT_HASH", "OTEL_VCS_HEAD_REVSION"},
|
||||||
semconv.VCSRefHeadTypeKey: {"GIT_TYPE", "OTEL_VCS_HEAD_TYPE"},
|
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 k, keys := range envs {
|
||||||
for _, key := range keys {
|
for _, key := range keys {
|
||||||
|
|||||||
@ -5,6 +5,7 @@ import (
|
|||||||
|
|
||||||
httplog "github.com/foomo/keel/net/http/log"
|
httplog "github.com/foomo/keel/net/http/log"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
semconv "go.opentelemetry.io/otel/semconv/v1.37.0"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
|
|
||||||
"github.com/foomo/keel/log"
|
"github.com/foomo/keel/log"
|
||||||
@ -48,7 +49,7 @@ func ServerError(l *zap.Logger, w http.ResponseWriter, r *http.Request, code int
|
|||||||
} else {
|
} else {
|
||||||
l = log.WithError(l, err)
|
l = log.WithError(l, err)
|
||||||
l = log.WithHTTPRequest(l, r)
|
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
|
// w.Header().Set(keelhttp.HeaderXError, err.Error()) TODO make configurable with better value
|
||||||
http.Error(w, http.StatusText(code), code)
|
http.Error(w, http.StatusText(code), code)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user