Skip to content

Tracer

Serinus uses an internal system to allow you to trace the request and response of your application. This system is called Tracer.

Create a Tracer

To start tracing a request, you need to create a class that extends the Tracer class and override the methods that you want to trace.

dart
import 'package:serinus/serinus.dart';

class ServerTimingTracer extends Tracer {
  final Map<String, int> _timings = {};

  ServerTimingTracer() : super('ServerTimingTracer');

  @override
  Future<void> onRequestReceived(TraceEvent event, Duration delta) async {
    _timings['${event.name.name}-${event.traced}'] = delta.inMilliseconds;
    return;
  }

  @override
  Future<void> onHandle(TraceEvent event, Duration delta) async {
    _timings['${event.name.name}-${event.traced}'] = delta.inMilliseconds;
    return;
  }

  @override
  Future<void> onAfterHandle(TraceEvent event, Duration delta) async {
    _timings['${event.name.name}-${event.traced}'] = delta.inMilliseconds;
    return;
  }

  @override
  Future<void> onResponse(TraceEvent event, Duration delta) async {
    _timings['${event.name.name}-${event.traced}'] = delta.inMilliseconds;
    String label = '';
    for (String event in _timings.keys) {
      label +=
          '$event;dur=${(_timings[event]?.isNegative ?? false) ? 0 : _timings[event]},';
    }

    event.context?.res.headers['Server-Timing'] = label;
  }
}

These are the methods that you can override:

MethodDescriptionCalled multiple times per lifecycle
onRequestReceivedCalled when a request is received.
onRequestCalled when a onRequest hook is executed
onTransformCalled when the transform hook is executed
onParseCalled when the parse hook is executed
onMiddlewareCalled when a middleware is executed
onBeforeHandleCalled when the beforeHandle hook is executed
onHandlerCalled when the handler is executed
onAfterHandleCalled when the afterHandle hook is executed
onResponseCalled when the response is being closed

Using a Tracer

To use a tracer, you need to pass an instance of the tracer to the trace method of the SerinusApplication instance. You can add multiple tracers to the same application.

dart
import 'package:serinus/serinus.dart';

Future<void> main() async {
  final app = await serinus.createApplication(entrypoint: AppModule());
  app.trace(ServerTimingTracer());
  await app.serve();
}

TraceEvent

The TraceEvent class is a class that contains information about the current event that is being traced. This class is passed to the methods of the Tracer class.

The TraceEvent class has the following properties:

PropertyDescription
requestThe Request object of the current request. (Can be null)
contextThe RequestContext object of the current request. (Can be null)
nameThe name of the event.
timestampThe DateTime of the event.
beginWhether the event is the beginning of a cycle.
tracedThe traced event.

The traced property follows a naming convention of:

  • r-* for route-related events (e.g. route handler, route hooks)
  • m-* for middleware-related events
  • h-* for hooks-related events (e.g. global hooks)

Built with 💙 and Dart 🎯 | One of the 🐤 of Avesbox