Tracing Configuration#
NeMo Guardrails includes a tracing feature that allows you to monitor and log interactions for better observability and debugging. Tracing can be easily configured via the existing config.yml
file. Below are the steps to enable and configure tracing in your project.
Enabling Tracing#
To enable tracing, set the enabled flag to true under the tracing section in your config.yml
:
tracing:
enabled: true
Important
You must install the necessary dependencies to use tracing adapters.
pip install "opentelemetry-api opentelemetry-sdk aiofiles"
Configuring Tracing Adapters#
Tracing supports multiple adapters that determine how and where the interaction logs are exported. You can configure one or more adapters by specifying them under the adapters list. Below are examples of configuring the built-in OpenTelemetry
and FileSystem
adapters:
tracing:
enabled: true
adapters:
- name: OpenTelemetry
service_name: "nemo_guardrails_service"
exporter: "console" # Options: "console", "zipkin", etc.
resource_attributes:
env: "production"
- name: FileSystem
filepath: './traces/traces.jsonl'
Warning
The “console” is intended for debugging and demonstration purposes only and should not be used in production environments. Using this exporter will output tracing information directly to the console, which can interfere with application output, distort the user interface, degrade performance, and potentially expose sensitive information. For production use, please configure a suitable exporter that sends tracing data to a dedicated backend or monitoring system.
OpenTelemetry Adapter#
The OpenTelemetry
adapter integrates with the OpenTelemetry framework, allowing you to export traces to various backends. Key configuration options include:
• service_name
: The name of your service.
• exporter
: The type of exporter to use (e.g., console, zipkin).
• resource_attributes
: Additional attributes to include in the trace resource (e.g., environment).
FileSystem Adapter#
The FileSystem
adapter exports interaction logs to a local JSON Lines file. Key configuration options include:
• filepath
: The path to the file where traces will be stored. If not specified, it defaults to ./.traces/trace.jsonl
.
Example Configuration#
Below is a comprehensive example of a config.yml
file with both OpenTelemetry
and FileSystem
adapters enabled:
tracing:
enabled: true
adapters:
- name: OpenTelemetry
service_name: "nemo_guardrails_service"
exporter: "zipkin"
resource_attributes:
env: "production"
- name: FileSystem
filepath: './traces/traces.jsonl'
To use this configuration, you must ensure that Zipkin is running locally or is accessible via the network.
Using Zipkin as an Exporter#
To use Zipkin
as an exporter, follow these steps:
Install the Zipkin exporter for OpenTelemetry:
pip install opentelemetry-exporter-zipkin
Run the
Zipkin
server using Docker:docker run -d -p 9411:9411 openzipkin/zipkin
Registering OpenTelemetry Exporters#
You can also use other OpenTelemetry exporters by registering them in the config.py
file. To do so you need to use register_otel_exporter
and register the exporter class.Below is an example of registering the Jaeger
exporter:
# This assumes that Jaeger exporter is installed
# pip install opentelemetry-exporter-jaeger
from opentelemetry.exporter.jaeger.thrift import JaegerExporter
from nemoguardrails.tracing.adapters.opentelemetry import register_otel_exporter
register_otel_exporter(JaegerExporter, "jaeger")
Then you can use it in the config.yml
file as follows:
tracing:
enabled: true
adapters:
- name: OpenTelemetry
service_name: "nemo_guardrails_service"
exporter: "jaeger"
resource_attributes:
env: "production"
Custom InteractionLogAdapters#
NeMo Guardrails allows you to extend its tracing capabilities by creating custom InteractionLogAdapter
classes. This flexibility enables you to transform and export interaction logs to any backend or format that suits your needs.
Implementing a Custom Adapter#
To create a custom adapter, you need to implement the InteractionLogAdapter
abstract base class. Below is the interface you must follow:
from abc import ABC, abstractmethod
from nemoguardrails.tracing import InteractionLog
class InteractionLogAdapter(ABC):
name: Optional[str] = None
@abstractmethod
async def transform_async(self, interaction_log: InteractionLog):
"""Transforms the InteractionLog into the backend-specific format asynchronously."""
raise NotImplementedError
async def close(self):
"""Placeholder for any cleanup actions if needed."""
pass
async def __aenter__(self):
"""Enter the runtime context related to this object."""
return self
async def __aexit__(self, exc_type, exc_value, traceback):
"""Exit the runtime context related to this object."""
await self.close()
Registering Your Custom Adapter#
After implementing your custom adapter, you need to register it so that NemoGuardrails can recognize and utilize it. This is done by adding a registration call in your config.py:
from nemoguardrails.tracing.adapters.registry import register_log_adapter
from path.to.your.adapter import YourCustomAdapter
register_log_adapter(YourCustomAdapter, "CustomLogAdapter")
Example: Creating a Custom Adapter#
Here’s a simple example of a custom adapter that logs interaction logs to a custom backend:
from nemoguardrails.tracing.adapters.base import InteractionLogAdapter
from nemoguardrails.tracing import InteractionLog
class MyCustomLogAdapter(InteractionLogAdapter):
name = "MyCustomLogAdapter"
def __init__(self, custom_option1: str, custom_option2: str):
self.custom_option1 = custom_option1
self.custom_option2 = custom
def transform(self, interaction_log: InteractionLog):
# Implement your transformation logic here
custom_format = convert_to_custom_format(interaction_log)
send_to_custom_backend(custom_format)
async def transform_async(self, interaction_log: InteractionLog):
# Implement your asynchronous transformation logic here
custom_format = convert_to_custom_format(interaction_log)
await send_to_custom_backend_async(custom_format)
async def close(self):
# Implement any necessary cleanup here
await cleanup_custom_resources()
Updating config.yml
with Your CustomLogAdapter
Once registered, you can configure your custom adapter in the config.yml
like any other adapter:
tracing:
enabled: true
adapters:
- name: MyCustomLogAdapter
custom_option1: "value1"
custom_option2: "value2"
By following these steps, you can leverage the built-in tracing adapters or create and integrate your own custom adapters to enhance the observability of your NeMo Guardrails powered applications. Whether you choose to export logs to the filesystem, integrate with OpenTelemetry, or implement a bespoke logging solution, tracing provides the flexibility to meet your requirements.