The GalileoLogger
class provides the most granular control over logging in Galileo. While the wrappers and @log decorator are recommended for most use cases, the GalileoLogger
gives you complete flexibility when you need it.
Overview
The GalileoLogger
class allows you to:
- Manually create and manage traces
- Add spans of different types to your traces
- Control exactly what data gets logged
- Explicitly manage when traces are flushed to Galileo
This approach requires more code than using wrappers or decorators but gives you the most control over the logging process.
Basic Usage
Here’s a simple example of using the GalileoLogger
to log an LLM call:
from galileo import GalileoLogger
# Create a logger instance with project and log stream
logger = GalileoLogger(project="my-project", log_stream="my-log-stream")
# Start a new trace
trace = logger.start_trace("Say this is a test")
# Add an LLM span to the trace
logger.add_llm_span(
input="Say this is a test",
output="Hello, this is a test",
model="gpt-4o",
num_input_tokens=10,
num_output_tokens=3,
total_tokens=13,
duration_ns=1000,
)
# Conclude the trace with the final output
logger.conclude(output="Hello, this is a test", duration_ns=1000)
# Flush the trace to Galileo
logger.flush()
Detailed API
Initialization
from galileo import GalileoLogger
# Initialize with default settings (uses environment variables)
logger = GalileoLogger()
# Or specify project and log stream
logger = GalileoLogger(
project="my-project",
log_stream="my-log-stream"
)
Starting a Trace
# Start a basic trace
trace = logger.start_trace(input="User query")
# Start a trace with additional metadata
trace = logger.start_trace(
input="User query",
name="User Interaction",
tags=["production", "user-123"],
metadata={"session_id": "abc123", "user_id": "user-456"},
duration_ns=1000000, # Optional duration in nanoseconds
created_at=datetime.now() # Optional creation timestamp
)
Adding Spans
The GalileoLogger
supports adding different types of spans to your traces:
LLM Spans
logger.add_llm_span(
input="What is the capital of France?",
output="The capital of France is Paris.",
model="gpt-4o",
tools=None, # Optional list of tools used
name="Capital Query", # Optional name
duration_ns=1000000, # Optional duration in nanoseconds
metadata={"temperature": "0.7"}, # Optional metadata
tags=["geography"], # Optional tags
num_input_tokens=10, # Optional token counts
num_output_tokens=5,
total_tokens=15,
temperature=0.7, # Optional model parameters
status_code=200, # Optional status code
time_to_first_token_ns=500000 # Optional time to first token
)
Retriever Spans
logger.add_retriever_span(
input="Query about Roman history",
output=["Rome was founded in 753 BC...", "The Roman Empire reached its peak..."],
name="History Retrieval", # Optional
duration_ns=500000, # Optional
metadata={"source": "history_db"}, # Optional
tags=["history"], # Optional
status_code=200 # Optional
)
logger.add_tool_span(
input=json.dumps({"operation": "add", "numbers": [1, 2, 3]}),
output=json.dumps({"result": 6}),
name="Calculator", # Optional
duration_ns=100000, # Optional
metadata={"tool_version": "1.0"}, # Optional
tags=["math"], # Optional
status_code=200, # Optional
tool_call_id="tool-123" # Optional
)
Workflow Spans
# Start a workflow span
workflow_span = logger.add_workflow_span(
input="Process user request",
output=None, # Can be set later
name="Main Process", # Optional
duration_ns=None, # Optional, can be set later
metadata={"workflow_type": "user_request"}, # Optional
tags=["workflow"] # Optional
)
# Later, you can conclude the workflow span when concluding the trace
Concluding and Flushing
# Conclude the trace with the final output
logger.conclude(
output="Final response to the user",
duration_ns=2000000, # Optional duration in nanoseconds
status_code=200, # Optional status code
conclude_all=False # Whether to conclude all open spans
)
# Flush the trace to Galileo
logger.flush()
Advanced Usage
Creating a Single-Span Trace
For simple LLM calls, you can create a trace with a single LLM span in one step:
logger.add_single_llm_span_trace(
input="What is the capital of France?",
output="The capital of France is Paris.",
model="gpt-4o",
tools=None,
name="Capital Query",
duration_ns=1000000,
metadata={"temperature": "0.7"},
tags=["geography"],
num_input_tokens=10,
num_output_tokens=5,
total_tokens=15
)
Complex Trace Example
Here’s an example of creating a more complex trace with multiple spans:
from galileo import GalileoLogger
from datetime import datetime
logger = GalileoLogger(project="my-project", log_stream="my-log-stream")
# Start a trace for a user query
trace = logger.start_trace(
input="Who's a good bot?",
name="User Query",
tags=["bot-interaction"]
)
# Add a retriever span for document retrieval
logger.add_retriever_span(
input="Who's a good bot?",
output=["Research shows that I am a good bot."],
name="Document Retrieval",
duration_ns=1000000
)
# Add an LLM span for generating a response
logger.add_llm_span(
input="Who's a good bot?",
output="I am!",
model="gpt-4o",
name="Response Generation",
num_input_tokens=25,
num_output_tokens=3,
total_tokens=28,
duration_ns=1000000
)
# Conclude the trace
logger.conclude(output="I am!", duration_ns=2000000)
# Flush the trace to Galileo
logger.flush()
Best Practices
-
Use higher-level abstractions when possible: The @log
decorator and wrappers are easier to use and less error-prone.
-
Flush traces when appropriate: Call flush()
at the end of a request or user interaction to ensure data is sent to Galileo.
-
Include relevant metadata: Add tags and metadata to make it easier to filter and analyze your traces.
-
Structure spans logically: Create a span hierarchy that reflects the logical structure of your application.
-
Handle errors gracefully: Include status codes and error information in your spans to help with debugging.