Skip to content

About

Langfuse helps you ship AI Agents/Products from prototype to production and beyond.

Topics

Resources

Stars

4 stars

Watchers

1 watching

Forks

Repository files navigation

Version

All Contributors

Quarkus Langfuse

A Quarkus extension for Langfuse, the open-source LLM engineering platform. This extension provides a type-safe REST client (based on the Langfuse Java SDK), DevServices for zero-config local development, and a Dev UI card for quick access to the Langfuse dashboard.

Langfuse helps you ship AI Agents and Products from prototype to production and beyond. It provides observability (traces, sessions, scores), prompt management (versioning, deployment, A/B testing), and evaluation (datasets, experiments, LLM-as-a-judge) for LLM-powered applications.

Features

  • Type-safe Langfuse API client - Synchronous and asynchronous clients covering the full Langfuse public API (traces, ingestion, prompts, scores, datasets, observations, sessions, and more), built on the Quarkus REST Client Reactive.
  • Higher-level API operations - Curated LangfuseOperations and AsyncLangfuseOperations (Mutiny) beans covering seventeen domains - models, datasets and dataset items, LLM connections, score configs, evaluation rules, evaluators and their versions, prompts, annotation queues and their items, comments, scores, observations, experiments and experiment items, and blob storage integrations. They offer find-by-id and find-by-name, existence checks, filtered views, lazy pagination with short-circuiting, idempotent resource initialization, and batch deletes that report an outcome per identifier, with an api() escape hatch to the raw client.
  • CDI integration - Inject LangfuseApi, LangfuseOperations, or AsyncLangfuseOperations directly into your beans.
  • DevServices - Automatically starts a complete Langfuse stack (Langfuse server, PostgreSQL, ClickHouse, Redis, MinIO, and Worker) in dev and test mode using Testcontainers. No manual setup required.
  • Dev UI - Provides a Dev UI card with a direct link to the Langfuse dashboard running in your local DevServices instance.
  • Native image support - Compatible with GraalVM native image compilation.
  • OpenTelemetry integration - When quarkus-opentelemetry is on the classpath, automatically exports AI-related spans to Langfuse. Zero configuration needed with DevServices.

Compatibility

Langfuse v4

This version of the extension requires Langfuse v4. If you are upgrading from a previous version of the extension that targeted Langfuse v3, complete the Langfuse v4 migration before upgrading the extension.

OpenAPI spec validation

The Langfuse v4 OpenAPI spec uses the const keyword (an OpenAPI 3.1 feature) while declaring version 3.0.1. The openapi-generator-maven-plugin cannot validate the spec with this incompatibility, so skipValidateSpec is set to true in the langfuse-client module's POM. This does not affect code generation -- only the upfront validation check is bypassed. This is tracked upstream as openapi-generator#10445.

Installation

Add the extension dependency to your project:

Maven

<dependency>
    <groupId>io.quarkiverse.langfuse</groupId>
    <artifactId>quarkus-langfuse</artifactId>
    <version>${quarkus-langfuse.version}</version>
</dependency>

Gradle

implementation 'io.quarkiverse.langfuse:quarkus-langfuse:${quarkus-langfuse.version}'

Configuration

Configure your Langfuse connection in application.properties:

quarkus.langfuse.base-url=https://cloud.langfuse.com
quarkus.langfuse.public-key=pk-lf-...
quarkus.langfuse.secret-key=sk-lf-...

Note: When DevServices is enabled (the default in dev/test mode), base-url, username, and password are automatically configured for you. You only need to set these properties when connecting to an external Langfuse instance or in production.

Configuration Reference

Property Type Default Description
quarkus.langfuse.base-url String required Base URL of the Langfuse server
quarkus.langfuse.public-key String required Langfuse project public key
quarkus.langfuse.secret-key String required Langfuse project secret key
quarkus.langfuse.timeout Duration 1m Default timeout for Langfuse API calls
quarkus.langfuse.connect-timeout Duration ${quarkus.langfuse.timeout} Timeout to establish a connection
quarkus.langfuse.read-timeout Duration ${quarkus.langfuse.timeout} Timeout for receiving a response
quarkus.langfuse.log-requests boolean false Log outgoing requests
quarkus.langfuse.log-responses boolean false Log incoming responses
quarkus.langfuse.pretty-print boolean false Pretty-print JSON bodies in logs
quarkus.langfuse.otel.enabled boolean true Enable/disable OpenTelemetry integration (build time, defaults to quarkus.otel.enabled)
quarkus.langfuse.otel.export-target String ALL Export target (build time): ALL (Langfuse + other OTLP backends) or LANGFUSE_ONLY
quarkus.langfuse.otel.trace-ingestion-url String <base-url>/api/public/otel/v1/traces Override the OTLP trace ingestion endpoint (applies when export-target=ALL)
quarkus.langfuse.otel.span-filter String AI_ONLY Span filter: AI_ONLY (AI spans + ancestors) or ALL (applies when export-target=ALL)

Usage

Simply inject LangfuseApi into your CDI beans. The extension automatically configures and provides the implementation:

import com.langfuse.api.LangfuseApi;

@ApplicationScoped
public class MyService {

    @Inject
    LangfuseApi langfuseApi;

    public void listObservations() {
        // Synchronous call
        var observations = langfuseApi.observations().observationsGetMany(/* parameters */);

        // Asynchronous call
        var asyncObservations = langfuseApi.asyncObservations().observationsGetMany(/* parameters */);
    }

    public void listPrompts() {
        var prompts = langfuseApi.prompts().promptsList(/* parameters */);
    }

    public void listScores() {
        var scores = langfuseApi.scoresV3().scoresV3GetManyV3(/* parameters */);
    }

    public void checkHealth() {
        var health = langfuseApi.health().healthHealth();
    }
}

Available API Groups

The LangfuseApi bean provides access to the full Langfuse public API. Each API group is available as a method, with both synchronous and asynchronous variants (e.g., trace() / asyncTrace()):

API Group Description
health() Health check endpoints
opentelemetry() OpenTelemetry trace ingestion (recommended for v4)
observations() Query observations with selective fields and cursor pagination (v2)
scores() Create scores and query scores (v2, deprecated in events_only mode)
scoresV3() Query scores with polymorphic values and cursor pagination (v3, recommended)
experiments() List experiments and experiment items (dataset runs)
prompts() Manage, version, and retrieve prompts
promptVersion() Manage individual prompt versions
scoreConfigs() Manage score configurations
datasets() Create and manage datasets
datasetItems() Manage dataset items
datasetRunItems() Manage dataset run items
models() Create, upsert, and manage model definitions and pricing
evaluators() Create and manage evaluators (v2)
evaluationRules() Create and manage evaluation rules (v2)
projects() Manage projects and API keys
organizations() Manage organization memberships
comments() Manage comments on traces
media() Upload and manage media attachments
metrics() Query usage metrics (v2)
annotationQueues() Manage annotation queues for human review
llmConnections() Manage LLM provider connections
blobStorageIntegrations() Manage blob storage integrations
scim() SCIM user provisioning
feedback() Submit feedback about Langfuse features
unstableDashboardWidgets() Create, list, update, and delete dashboard widgets (unstable)
unstableDashboards() Create, list, update, and delete dashboards with placements (unstable)
ingestion() Legacy batch ingestion (deprecated — use opentelemetry())
trace() Legacy trace endpoints (deprecated in v4 events_only mode)
sessions() Legacy session endpoints (deprecated in v4 events_only mode)
legacyObservationsV1() Legacy observations (v1, deprecated — use observations())
legacyMetricsV1() Legacy metrics (v1, deprecated — use metrics())
legacyScoreV1() Legacy score deletion (v1, deprecated)

OpenTelemetry Integration

When the quarkus-opentelemetry extension is on the classpath, the Langfuse extension automatically exports OpenTelemetry span data to Langfuse. No additional configuration is needed -- authentication is derived from your existing quarkus.langfuse.username and quarkus.langfuse.password settings.

Export Target

The quarkus.langfuse.otel.export-target property (build time) controls how spans are exported:

  • ALL (default) -- The extension registers a dedicated Langfuse span processor that runs alongside any other OpenTelemetry exporters you have configured. Spans are exported to both Langfuse and your standard OTLP backend (Jaeger, Zipkin, or any other collector). In this mode, only AI-related spans are sent to Langfuse by default (see AI Span Filtering below), and the gen_ai.prompt / gen_ai.completion attributes are automatically mapped to the Langfuse trace input and output.

  • LANGFUSE_ONLY -- The standard OpenTelemetry OTLP exporter is configured to send directly to Langfuse. No separate span processor is registered and no additional OTLP backend receives spans. All spans are exported to Langfuse without filtering. This is equivalent to the manual configuration described in the Quarkus LangChain4j docs, but handled automatically by the extension.

quarkus.langfuse.otel.export-target=LANGFUSE_ONLY

AI Span Filtering

When export-target=ALL (the default), only AI-related spans -- those carrying gen_ai.* OpenTelemetry Semantic Convention attributes -- and their ancestor spans are exported to Langfuse. This avoids cluttering your Langfuse dashboard with HTTP, database, or other infrastructure spans.

The gen_ai.prompt and gen_ai.completion attributes are automatically mapped to the Langfuse trace input and output, giving you immediate visibility into what was sent to and received from the LLM.

To export all spans instead, set:

quarkus.langfuse.otel.span-filter=ALL

Quarkus LangChain4j Integration

When both quarkus-opentelemetry and quarkus-langchain4j are on the classpath, the extension automatically enables LangChain4j prompt tracing. Prompt content, LLM responses, tool arguments, and tool results are all included in the OpenTelemetry spans emitted by LangChain4j -- and therefore visible in Langfuse traces -- without any manual configuration.

These defaults are set at a low priority, so you can override any of them in application.properties or via environment variables.

Zero-Config with DevServices

When DevServices is running, the OTel integration works out of the box with no configuration at all. The Langfuse base URL, public key, and secret key are all provided automatically.

Disabling the Integration

To disable the OpenTelemetry integration entirely (for example, if you want to manage your own OTel exporters):

quarkus.langfuse.otel.enabled=false

When quarkus-opentelemetry is not on the classpath, the integration is automatically skipped.

DevServices

In dev and test mode, the extension automatically starts a complete Langfuse stack using Testcontainers:

  • Langfuse server - The main Langfuse application
  • PostgreSQL - Primary database
  • ClickHouse - Analytics database
  • Redis - Cache
  • MinIO - Object storage (for media/blob storage)
  • Worker - Background job processing

No configuration is needed - just add the extension and run quarkus dev. The extension automatically configures quarkus.langfuse.base-url, quarkus.langfuse.username, and quarkus.langfuse.password to point to the DevServices instance.

DevServices Configuration

DevServices can be customized under quarkus.langfuse.devservices:

Property Type Default Description
quarkus.langfuse.devservices.enabled boolean true Enable/disable DevServices
quarkus.langfuse.devservices.shared boolean true Share containers across applications
quarkus.langfuse.devservices.service-name String langfuse Label for container discovery
quarkus.langfuse.devservices.langfuse.image-name String (Langfuse default) Langfuse server container image
quarkus.langfuse.devservices.langfuse.port int 8080 Langfuse server port
quarkus.langfuse.devservices.langfuse.username String quarkus Project public key
quarkus.langfuse.devservices.langfuse.password String quarkuslangfuse Project secret key
quarkus.langfuse.devservices.langfuse.startup-timeout Duration PT3M Container startup timeout

The Langfuse server also has properties to configure the initial organization, project, and user. See the full configuration reference for details.

Dev UI

When running in dev mode (quarkus dev), the extension adds a Langfuse card to the Quarkus Dev UI. The card includes a link to the Langfuse web dashboard running in your DevServices container, allowing you to browse traces, manage prompts, view scores, and more directly from your development environment.

Documentation

The full documentation is available at https://docs.quarkiverse.io/quarkus-langfuse/dev/index.html.

Contributors ✨

Thanks goes to these wonderful people (emoji key):

Eric Deandrea
Eric Deandrea

💻 🚧 ⚠️ 🤔 🖋 📖
Bill Burke
Bill Burke

💻 🚧 🖋 📖 🤔

This project follows the all-contributors specification. Contributions of any kind welcome!

About

Langfuse helps you ship AI Agents/Products from prototype to production and beyond.

Topics

Resources

Stars

4 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages