Skip to content

Conversation

@kxzk
Copy link
Contributor

@kxzk kxzk commented Nov 9, 2025

Summary

  • Implements serialization layer for converting Langfuse domain models to OpenTelemetry span attributes
  • Provides methods to transform user-friendly trace/observation attributes into internal OTel format
  • Handles metadata flattening with dot notation and safe JSON serialization

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, ENVIRONMENT constants: 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
    • Private helpers: #normalize_attrs, #get_hash_value, #build_observation_base_attributes, #add_prompt_attributes
  • New: spec/langfuse/otel_attributes_spec.rb (364 lines)

    • Complete test coverage for trace attribute conversion
    • Tests for observation attribute conversion (span, generation, event)
    • Tests for metadata flattening with nested structures
    • Tests for JSON serialization edge cases (nil, strings, objects, errors)
    • Tests for prompt attribute handling (including fallback detection)
  • Modified: lib/langfuse.rb - Added require for otel_attributes module

  • Modified: .gitignore - Added langfuse-python/ to ignored files

Design

The module provides a clean separation between user-facing domain models and internal OTel representation:

  • Accepts both attribute objects and hashes (flexible input)
  • Handles both symbol and string hash keys
  • Removes nil values from output (clean span attributes)
  • Flattens nested metadata into dot-notation keys for OTel compatibility
  • Skips prompt attributes when 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

@kxzk kxzk changed the title feat: add OTel attributes serialization layer (#7) Add OTel attributes serialization layer Nov 9, 2025
@kxzk kxzk marked this pull request as ready for review November 11, 2025 23:49
Copilot AI review requested due to automatic review settings November 11, 2025 23:50
Copilot finished reviewing on behalf of kxzk November 11, 2025 23:51
Copy link

Copilot AI left a 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 (Types module) 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
@kxzk
Copy link
Contributor Author

kxzk commented Nov 12, 2025

- Improves code maintainability by separating concerns
- Makes recursive flattening logic more testable in isolation
- Reduces complexity in flatten_metadata method through extraction
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement Langfuse::OtelAttributes module for converting domain models to OTel span attributes

1 participant