-
Notifications
You must be signed in to change notification settings - Fork 3
Add OTel attributes serialization layer #25
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR implements a serialization layer for converting Langfuse domain models to OpenTelemetry span attributes, providing a clean separation between user-facing domain models and internal OTel representation. The implementation introduces type-safe attribute classes and serialization utilities with comprehensive test coverage.
Key Changes
- Adds domain model type definitions (
Typesmodule) with attribute classes for traces and observations - Implements OTel serialization layer that converts domain models to OpenTelemetry attribute format
- Provides metadata flattening with JSON serialization for nested structures
Reviewed Changes
Copilot reviewed 5 out of 6 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| lib/langfuse/types.rb | Defines attribute classes (SpanAttributes, GenerationAttributes, EmbeddingAttributes, TraceAttributes) and constants for observation types and severity levels |
| lib/langfuse/otel_attributes.rb | Implements serialization methods to convert Langfuse attributes to OTel format with metadata flattening and JSON serialization |
| spec/langfuse/types_spec.rb | Comprehensive tests for all attribute classes covering initialization, to_h conversion, and inheritance |
| spec/langfuse/otel_attributes_spec.rb | Tests for serialization methods including edge cases for metadata flattening, JSON serialization, and prompt handling |
| lib/langfuse.rb | Adds require statements for new types and otel_attributes modules |
| .gitignore | Adds entries for langfuse-python/, langfuse-js/, and AGENTS.md |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Nested hashes were being serialized as JSON strings, losing structure - Now preserves hierarchy through dot-notation keys for better queries - Enables OpenTelemetry backends to filter on individual nested fields
- Improves code maintainability by separating concerns - Makes recursive flattening logic more testable in isolation - Reduces complexity in flatten_metadata method through extraction
Summary
Changes
New:
lib/langfuse/otel_attributes.rb(246 lines)TRACE_*constants: 8 trace attribute keys (name, user_id, session_id, input, output, metadata, tags, public)OBSERVATION_*constants: 12 observation attribute keys (type, input, output, metadata, level, status_message, model, usage_details, cost_details, prompt, completion_start_time, model_parameters)VERSION,RELEASE,ENVIRONMENTconstants: 3 common attribute keys#create_trace_attributes: Converts TraceAttributes to OTel format#create_observation_attributes: Converts observation attributes to OTel format#serialize: Safe JSON serialization with error handling#flatten_metadata: Converts nested metadata to dot-notation keys#normalize_attrs,#get_hash_value,#build_observation_base_attributes,#add_prompt_attributesNew:
spec/langfuse/otel_attributes_spec.rb(364 lines)Modified:
lib/langfuse.rb- Added require for otel_attributes moduleModified:
.gitignore- Added langfuse-python/ to ignored filesDesign
The module provides a clean separation between user-facing domain models and internal OTel representation:
is_fallback: true(avoids polluting traces with cached fallback data)Test Coverage
100% coverage of otel_attributes module (364 lines of specs testing all public methods, constants, and edge cases)
References
Closes #7