event

package
v4.29.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 13, 2026 License: Apache-2.0 Imports: 3 Imported by: 0

README

Event Logger

This package enables logging using AccelByte's Event Log Format in go-restful apps.

Usage

Importing
import (
	"github.com/AccelByte/go-restful-plugins/v4/pkg/logger/event"
	"github.com/AccelByte/go-restful-plugins/v4/pkg/util"
)
Log events on all endpoints
ws := new(restful.WebService)
ws.Filter(event.Log("realm", "serviceName", util.ExtractDefault))
Log events on a specific endpoint
ws := new(restful.WebService)
ws.Route(ws.GET("/user/{id}").
    Filter(event.Log("realm", "serviceName", util.ExtractDefault)).
    To(func(request *restful.Request, response *restful.Response) {
}))

event.Log doesn't log every request. It writes one event line after the request, and only when the handler set an event with a non-zero event ID by calling one of the functions in Set the event. A request that sets no event produces no line.

Actor User ID & Namespace

If you are using IAM Auth Filter, util.ExtractDefault extracts the actor's user ID, client ID and namespace from the iam.JWTClaims in the request, the session and flight IDs from the X-Ab-SessionID and x-flight-id headers, and the request's OpenTelemetry trace ID as trace_id, the same value as the access log's trace_id. The trace ID is empty when the request has no span and arrived without trace headers.

If you don't need these fields, pass nil as the extract function; the event line then leaves them empty.

If you are using your own auth filter, set the actor on the request in that filter, and pass your own extract function to event.Log. For example:

Set the attributes in the auth filter, for each request

// get token
token := parseToken(request)

// parse the JWT claims
claims := parseClaim(token)

// set the request attribute with claims
request.SetAttribute("userID", claims.Subject)
request.SetAttribute("clientID", claims.ClientID)
request.SetAttribute("namespace", claims.Namespace)

The extract function

extractFunc := func(req *restful.Request) (userID string, clientID []string, namespace string,
	traceID string, sessionID string, flightID string) {
	// the trace, session and flight IDs as util.ExtractDefault reads them
	_, _, _, traceID, sessionID, flightID = util.ExtractDefault(req)

	userID, _ = req.Attribute("userID").(string)
	if id, ok := req.Attribute("clientID").(string); ok {
		clientID = []string{id}
	}
	namespace, _ = req.Attribute("namespace").(string)

	return userID, clientID, namespace, traceID, sessionID, flightID
}

ws := new(restful.WebService)
ws.Route(ws.GET("/user/{id}").
    Filter(event.Log("realm", "serviceName", extractFunc)).
    To(func(request *restful.Request, response *restful.Response) {
}))
Target User ID & Namespace

To put target user ID & namespace to the log, call:

event.TargetUser(req *restful.Request, id, namespace string)
Set the event

To set the event's ID, type, level and message, call one of:

event.Debug(req *restful.Request, eventID int, eventType int, eventLevel int, msg string)
event.Info(req *restful.Request, eventID int, eventType int, eventLevel int, msg string)
event.Warn(req *restful.Request, eventID int, eventType int, eventLevel int, msg string)
event.Error(req *restful.Request, eventID int, eventType int, eventLevel int, msg string)
event.Fatal(req *restful.Request, eventID int, eventType int, eventLevel int, msg string)

The function sets the logrus level of the event line: Debug logs at debug level, Info at info level, and so on. Calling one again in the same request replaces the event set before.

event.Fatal exits the process. The event line is logged with logrus's Fatal, which calls os.Exit(1) after the request, so one request that sets a fatal event stops the whole service, and every service bundled with it in the same process.

Event lines are written with the global logrus logger, so the service's log level filters them: a service at warn level drops the lines of event.Info and event.Debug events.

Additional log fields

Add any additional log fields using

event.AdditionalFields(req *restful.Request, fields map[string]interface{})

Each call replaces the fields of the previous call in the same request, so pass all the fields in one call. The additional fields are added after the default fields, so a key with a default field's name overwrites it.

Event line fields
Field Value
event_id Event ID set by event.Debug, Info, Warn, Error or Fatal
event_type Event type set by the same call
event_level Event level set by the same call
msg Message set by the same call
realm realm passed to event.Log
service service passed to event.Log
log_type Always event
user_id User ID from the extract function
client_ids Client IDs from the extract function
namespace Namespace from the extract function
trace_id Trace ID from the extract function
session_id Session ID from the extract function
flight_id Flight ID from the extract function
target_user_ids Target user ID set by event.TargetUser
target_namespace Target namespace set by event.TargetUser
action Action set by event.Action
resp, status Never set by this package, so always 0 and empty
Timestamp format

By importing this package, or pkg/response, which imports it, the logrus formatter of the entire service is set to a text formatter with RFC3339 timestamps of up to millisecond precision (trailing zeros are dropped), and the time is converted to UTC. This timestamp format is required for the AccelByte Event Log service.

If you want to use your own format, call logrus.SetFormatter in your code, for example in main(). It replaces the formatter for the lines written after the call. To keep the time in UTC, wrap your formatter in event.UTCFormatter. This is the example of setting the timestamp format to RFC3339Nano in UTC:

logrus.SetFormatter(event.UTCFormatter{Formatter: &logrus.TextFormatter{TimestampFormat: time.RFC3339Nano}})

Documentation

Index

Constants

View Source
const (
	// TraceIDKey is the X-Ab-TraceID request header.
	//
	// Deprecated: X-Ab-TraceID is being replaced by the OpenTelemetry trace ID, which logs
	// write in the trace_id field. To read a request's trace ID, use util.ExtractDefault or the
	// span in req.Request.Context(). There is no replacement request header: callers receive the
	// trace ID in the X-Trace-Id response header that log.AccessLog sets, and continue a trace
	// with traceparent.
	TraceIDKey = "X-Ab-TraceID"

	// SessionIDKey is the X-Ab-SessionID request header.
	//
	// Deprecated: use constant.SessionID from pkg/constant.
	SessionIDKey = "X-Ab-SessionID"

	// FlightIDKey is the x-flight-id request header.
	//
	// Deprecated: use constant.FlightID from pkg/constant.
	FlightIDKey = "x-flight-id"
)

Variables

This section is empty.

Functions

func Action

func Action(req *restful.Request, action string)

Action injects the action to current event in the request

func AdditionalFields

func AdditionalFields(req *restful.Request, fields map[string]interface{})

AdditionalFields injects additional log fields to the event in the request

func Debug

func Debug(req *restful.Request, eventID int, eventType int, eventLevel int, msg string)

Debug sets the event level to debug along with the event ID and message

func Error

func Error(req *restful.Request, eventID int, eventType int, eventLevel int, msg string)

Error sets the event level to error along with the event ID and message

func Fatal

func Fatal(req *restful.Request, eventID int, eventType int, eventLevel int, msg string)

Fatal sets the event level to fatal along with the event ID and message

func Info

func Info(req *restful.Request, eventID int, eventType int, eventLevel int, msg string)

Info sets the event level to info along with the event ID and message

func Log

func Log(realm string, service string, fn extractAttribute) restful.FilterFunction

Log is a filter that will log incoming request with AccelByte's Event Log Format. fn extracts the actor, trace, session and flight IDs for the event line; with a nil fn, they are left empty.

func TargetUser

func TargetUser(req *restful.Request, id, namespace string)

TargetUser injects the target user ID and namespace to current event in the request

func Topic

func Topic(req *restful.Request, topic string)

Topic inject the topic to current event in the request

func Warn

func Warn(req *restful.Request, eventID int, eventType int, eventLevel int, msg string)

Warn sets the event level to warn along with the event ID and message

Types

type UTCFormatter

type UTCFormatter struct {
	logrus.Formatter
}

UTCFormatter implements logrus Formatter for custom log format

func (UTCFormatter) Format

func (formatter UTCFormatter) Format(log *logrus.Entry) ([]byte, error)

Format implements logrus Format for forcing time to UTC

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL