# DBNL Semantic Convention

## Mapping Fields to Semantically Understood Columns

DBNL ingests data using traces produced using telemetry frameworks with different semantic conventions as well as tabular logs with a user defined format.

To compute metrics and derive insights consistently across different data ingestion formats, we define a semantic convention for the data as stored within DBNL.

If you are using [OTEL Trace Ingestion](/v0.26.x/configuration/data-connections/otel-trace-ingestion.md) and the [OpenInference](https://github.com/Arize-ai/openinference/blob/main/spec/semantic_conventions.md) semantic convention, this happens automatically, see the table below for how data maps from one convention to another.

If you are using [SDK Log Ingestion](/v0.26.x/configuration/data-connections/sdk-log-ingestion.md) or [SQL Integration Ingestion](/v0.26.x/configuration/data-connections/sql-integration-ingestion.md) you need to ensure that your column names adhere to our semantic convention for best results.

## Required Fields

The following fields are required regardless of which ingestion method you are using:

* `input`: The text input to the LLM as a `string`.
* `output`: The text response from the LLM as a `string`.
* `timestamp`: The UTC timecode associated with the LLM call as a `timestamptz`.

## DBNL Semantic Convention

The DBNL Semantic Convention is a mapping from well known formats into types and names that DBNL can recognize.

| DBNL SemConv               | DBNL Type                                      | [OpenInference SemConv](https://github.com/Arize-ai/openinference/blob/main/spec/semantic_conventions.md) |
| -------------------------- | ---------------------------------------------- | --------------------------------------------------------------------------------------------------------- |
| **`input` (required)**     | `string`                                       | `ROOT:input.value`                                                                                        |
| **`output` (required)**    | `string`                                       | `ROOT:output.value`                                                                                       |
| **`timestamp` (required)** | `timestamptz`                                  | `ROOT:start_time`                                                                                         |
| `spans`                    | `list<SpanType>` ([see below](#spans-example)) | Raw list of spans                                                                                         |
| `status`                   | `category`                                     | `ROOT:status.code`                                                                                        |
| `duration_ms`              | `int`                                          | `ROOT:end_time - ROOT:start_time`                                                                         |
| `session_id`               | `string`                                       | `ROOT:session.id`                                                                                         |
| `trace_id`                 | `string`                                       | `ROOT:trace_id`                                                                                           |
| `total_token_count`        | `int`                                          | `sum(*:llm.token_count.total)`                                                                            |
| `prompt_token_count`       | `int`                                          | `sum(*:llm.token_count.prompt)`                                                                           |
| `completion_token_count`   | `int`                                          | `sum(*:llm.token_count.completion)`                                                                       |
| `total_cost`               | `float` (USD)                                  | `sum(*:llm.cost.total)`                                                                                   |
| `prompt_cost`              | `float` (USD)                                  | `sum(*:llm.cost.prompt)`                                                                                  |
| `completion_cost`          | `float` (USD)                                  | `sum(*:llm.cost.completion)`                                                                              |
| `tool_call_count`          | `int`                                          | `count(*) WHERE kind = "TOOL"`                                                                            |
| `tool_call_name_counts`    | `map<string, int>`                             | `count(*:tool.name)`                                                                                      |
| `tool_call_error_count`    | `int`                                          | `count(*:status.code = "ERROR") WHERE kind = "TOOL"`                                                      |
| `llm_call_count`           | `int`                                          | `count(*:openinference.span.kind == "LLM")`                                                               |
| `llm_call_model_counts`    | `map<string, int>`                             | `count(*:llm.model_name)`                                                                                 |
| `llm_call_error_count`     | `int`                                          | `count(*:status.code = "ERROR") WHERE kind = "LLM"`                                                       |

{% hint style="warning" %}
Note: `ROOT`, `FIRST`, `LAST` and `ANY` are used as aliases for certain spans in a trace.
{% endhint %}

### Spans Example

```
struct<
  trace_id: string, 
  span_id: string,
  trace_state: string,
  parent_span_id: string,
  name: string,
  kind: string,
  start_time: timestamptz,
  end_time: timestamptz,
  attributes: map<string, string>,
  events: list<
    struct<
      timestamp: timestamptz, 
      name: string, 
      attributes: map<string, string>
    >
  >, 
  links: list<
    struct<
      trace_id: string, 
      span_id: string, 
      trace_state: string, 
      attributes: map<string, string>
    >
  >, 
  status: struct<
    code: string, 
    message: string
  >
>
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.dbnl.com/v0.26.x/configuration/dbnl-semantic-convention.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
