MCPcopy Index your code
hub / github.com/amanbolat/ft

github.com/amanbolat/ft @v0.5.2

Chat with this repo
repository ↗ · DeepWiki ↗ · release v0.5.2 ↗ · + Follow
47 symbols 251 edges 6 files 5 documented · 11% updated 6mo agov0.5.2 · 2025-12-25★ 44
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

ft – function trace

Go Report Card GoDoc License

A lightweight library for tracing function execution with OpenTelemetry integration, structured logging, and metrics collection.

Why?

In most of my projects, I start by relying on simple logs to get quick insights into the application. As the project evolves, I usually add metrics and traces for improved observability, but setting up all the libraries can be time-consuming. This library allows you to enable the observability of your functions with just two lines of code.

Features

  • Structured logging using slog.
  • OpenTelemetry tracing integration.
  • Metrics for execution counts and duration.
  • Configurable log level.
  • Option to opt out of metrics and tracing.

Usage

Just add two lines to the beginning of the function:

func Do(ctx context.Context) (err error) {
    ctx, span := ft.Start(ctx, "main.Do", ft.WithErr(&err)) // Log when we enter the `Do` function.
    defer span.End()                                        // Log, trace and meter when we exit the `Do` function.

    err = errors.New("unexpected error")

    return
}

If you run the code above, you will see the following output:

time=2025-01-25T21:55:27.068+01:00 level=INFO msg="action started" action=main.Do
time=2025-01-25T21:55:27.069+01:00 level=ERROR msg="action ended" action=main.Do duration_ms=0.743 error="unexpected error"

Adding attributes dynamically

You can add attributes to a span after it has been created using the AddAttrs method. This is useful when you want to add contextual information that becomes available during function execution:

func ProcessUser(ctx context.Context, userID string) (err error) {
    ctx, span := ft.Start(ctx, "main.ProcessUser", ft.WithErr(&err))
    defer span.End()

    // Add initial attributes
    span.AddAttrs(slog.String("user_id", userID))

    user, err := fetchUser(userID)
    if err != nil {
        return err
    }

    // Add more attributes as they become available
    span.AddAttrs(
        slog.String("user_email", user.Email),
        slog.Bool("user_premium", user.IsPremium),
    )

    // Process user...
    return nil
}

The AddAttrs method is thread-safe and can be called multiple times throughout the function execution. All attributes will be included in the final log output and, if enabled, added to the OpenTelemetry span.

OpenTelemetry Integration

Setup OTEL tracer and meter globally and ft will start sending metrics and traces to the OTLP collector:

mp, _, _ := autometer.NewMeterProvider(context.Background())
otel.SetMeterProvider(mp)
tp, _, _ := autotracer.NewTracerProvider(context.Background())
otel.SetTracerProvider(tp)

ft.SetMetricsEnabled(true)
ft.SetTracingEnabled(true)

[!TIP] In the example above I use go-faster/sdk to setup OTEL based on environment variables.

Configuration

ft package provides many functions to configure its behaviour. See the table below:

Here's a markdown table with all the Set functions and their descriptions:

Function Description
SetDurationMetricUnit(unit string) Sets the global duration metric unit. Accepts either millisecond (ms) or second (s) as valid units. Defaults to millisecond if invalid unit is provided.
SetDefaultLogger(l *slog.Logger) Sets the global logger instance. Does nothing if nil logger is provided.
SetLogLevelOnFailure(level slog.Level) Sets the global log level for failure scenarios.
SetLogLevelOnSuccess(level slog.Level) Sets the global log level for success scenarios.
SetTracingEnabled(v bool) Enables or disables global tracing functionality.
SetMetricsEnabled(v bool) Enables or disables global metrics collection.
SetClock(c clockwork.Clock) Sets the global clock instance used for time-related operations.
SetAppendOtelAttrs(v bool) Enables or disables the appending of OpenTelemetry attributes globally.

Contribution

Release

We maintain our Changelog using git-cliff.

To create a new release, execute the following commands:

git cliff -o CHANGELOG.md -t vX.X.X --bump
git tag vX.X.X
gp origin master --tags

Extension points exported contracts — how you extend this code

Span (Interface)
Span represents a traced and logged operation that can be ended. [1 implementers]
ft.go
Option (FuncType)
(no doc)
ft.go

Core symbols most depended-on inside this repo

End
called by 16
ft.go
SetDefaultLogger
called by 15
global.go
Start
called by 15
ft.go
SetClock
called by 12
global.go
SetTracingEnabled
called by 7
global.go
AddAttrs
called by 6
ft.go
SetDurationMetricUnit
called by 4
global.go
SetMetricsEnabled
called by 3
global.go

Shape

Function 33
Method 8
Struct 4
FuncType 1
Interface 1

Languages

Go100%

Modules by API surface

ft_test.go19 symbols
ft.go15 symbols
global.go9 symbols
examples/simple/main.go3 symbols
ft_internal_test.go1 symbols

For agents

$ claude mcp add ft \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact