OpenTelemetry Protocol (OTLP)
OpenTelemetry 是一个供应商中立的开源可观测性框架,用于检测、生成、收集和导出观测数据,例如 traces, metrics 和 logs。 OpenTelemetry Protocol (OTLP) 定义了观测数据在观测源和中间进程(例如收集器和观测后端)之间的编码、传输机制。
OpenTelemetry Collectors
你可以很简单地将 GreptimeDB 配置为 OpenTelemetry 采集器写入的目标。 有关更多信息,请参阅 OTel Collector 和Grafana Alloy 示例。
HTTP 基础端点
适用于所有信号类型的HTTP 基础端点 URL:http{s}://<host>/v1/otlp
当需要将多种信号类型(指标、日志和链路追踪)发送到同一目标数据库时,这个统一端点非常有用,可以简化你的 OpenTelemetry 配置。
Metrics
GreptimeDB 通过原生支持 OTLP/HTTP 协议,可以作为后端存储服务来接收 OpenTelemetry 指标数据。
OTLP/HTTP API
使用下面的信息通过 Opentelemetry SDK 库发送 Metrics 到 GreptimeDB:
- URL:
https://<host>/v1/otlp/v1/metrics - Headers:
X-Greptime-DB-Name:<dbname>
Authorization:Basic认证,是<username>:<password>的 Base64 编码字符串。更多信息请参考 鉴权 和 HTTP API。
请求中使用 binary protobuf 编码 payload,因此你需要使用支持 HTTP/protobuf 的包。例如,在 Node.js 中,可以使用 exporter-trace-otlp-proto;在 Go 中,可以使用 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp;在 Java 中,可以使用 io.opentelemetry:opentelemetry-exporter-otlp;在 Python 中,可以使用 opentelemetry-exporter-otlp-proto-http。
包名可能会根据 OpenTelemetry 的发展发生变化,因此建议你参考 OpenTelemetry 官方文档以获取最新信息。
请参考 Opentelementry 的官方文档获取它所支持的编程语言的更多信息。
示例代码
下面是一些编程语言设置请求的示例代码:
- TypeScript
- Go
- Java
- Python
const auth = Buffer.from(`${username}:${password}`).toString('base64')
const exporter = new OTLPMetricExporter({
url: `https://${dbHost}/v1/otlp/v1/metrics`,
headers: {
Authorization: `Basic ${auth}`,
'X-Greptime-DB-Name': db,
},
timeoutMillis: 5000,
})
auth := base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s:%s", *username, *password)))
exporter, err := otlpmetrichttp.New(
context.Background(),
otlpmetrichttp.WithEndpoint(*dbHost),
otlpmetrichttp.WithURLPath("/v1/otlp/v1/metrics"),
otlpmetrichttp.WithHeaders(map[string]string{
"X-Greptime-DB-Name": *dbName,
"Authorization": "Basic " + auth,
}),
otlpmetrichttp.WithTimeout(time.Second*5),
)
String endpoint = String.format("https://%s/v1/otlp/v1/metrics", dbHost);
String auth = username + ":" + password;
String b64Auth = new String(Base64.getEncoder().encode(auth.getBytes()));
OtlpHttpMetricExporter exporter = OtlpHttpMetricExporter.builder()
.setEndpoint(endpoint)
.addHeader("X-Greptime-DB-Name", db)
.addHeader("Authorization", String.format("Basic %s", b64Auth))
.setTimeout(Duration.ofSeconds(5))
.build();
auth = f"{username}:{password}"
b64_auth = base64.b64encode(auth.encode()).decode("ascii")
endpoint = f"https://{host}/v1/otlp/v1/metrics"
exporter = OTLPMetricExporter(
endpoint=endpoint,
headers={"Authorization": f"Basic {b64_auth}", "X-Greptime-DB-Name": db},
timeout=5)
你可以在 Github 中找到可执行的 Demo:Go, Java, Python, and Node.js.
示例代码可能会根据 OpenTelemetry 的发展发生变化,因此建议你参考 OpenTelemetry 官方文档以获取最新信息。
关于示例代码,请参考 Opentelementry 的官方文档获取它所支持的编程语言获取更多信息。
兼容 Prometheus
从 v0.16 开始,GreptimeDB 为 OTLP 指标写入引入了一种 Prometheus 兼容模式。
如果指标以这种兼容模式写入,你可以像查询 Prometheus 原生指标一样使用 PromQL 直接查询这些指标。
如果你之前没有使用过 OTLP 指标写入,那么 GreptimeDB 会默认使用新的兼容模式。 否则,GreptimeDB 会对已经存在的表保留原有的数据模型,只有对新创建的指标表使用兼容模式写入。
GreptimeDB 会首先对数据进行预处理,包括:
- 将指标名(表名)和标签名转换成 Prometheus 风格的命名(例如:将
.替换为_)。具体信息请参考这里 - 默认丢弃一些 resource 属性和全部的 scope 属性。默认保存的 resource 属性列表可以参考这里。你可以通过配置项对这个行为进行调整
注意: OTLP 的 Sum 和 Histogram 指标的数据可能是增量时序(delta temporality)类型的。
GreptimeDB 将会直接保存它们,不会进行累计值(cumulative value)的计算。
参考这里获取更多背景信息。
你可以通过设置 HTTP 请求头来调整预处理的行为。以下是选项列表: You can set the HTTP headers to configure the pre-process behaviors. Here are the options:
x-greptime-otlp-metric-promote-all-resource-attrs: 保存所有 resource 资源。默认是false。x-greptime-otlp-metric-promote-resource-attrs: 如果不保存所有 resource 资源,需要保存的资源名称列表,用;连接。x-greptime-otlp-metric-ignore-resource-attrs: 如果保存所有的 resource 资源,需要丢弃的资源名称列表,用;连接。x-greptime-otlp-metric-promote-scope-attrs: 是否需要保存 scope 资源。默认是false。
数据模型
兼容 Prometheus 的 OTLP 指标数据模型按照下方的规则被映射到 GreptimeDB 数据模型中:
- Metric 的名称将被作为 GreptimeDB 表的名称,当表不存在时会自动创建。
- 只有特定 resource 属性会被默认保留。详情和配置选项见上一小节。属性在 GreptimeDB 表中会被作为 tag 列。
- 参考 Prometheus 数据模型了解更多数据模型信息。
- ExponentialHistogram 暂时未被支持。
如果你在 v0.16 之前使用 OTLP 指标,那么数据将以非兼容模式保存。以下是数据模型在映射上的差别:
- 所有的 Attribute,包含 resource 级别、scope 级别和 data_point 级别,都被作为 GreptimeDB 表的 tag 列。
- Summary 类型的每个 quantile 被作为单独的数据列,列名
greptime_pxx,其中 xx 是 quantile 的数据,如 90 / 99 等。
Logs
GreptimeDB 是能够通过 OTLP/HTTP 协议原生地消费 OpenTelemetry 日志。
OTLP/HTTP API
要通过 OpenTelemetry SDK 库将 OpenTelemetry 日志发送到 GreptimeDB,请使用以下信息:
- URL:
https://<host>/v1/otlp/v1/logs - Headers:
X-Greptime-DB-Name:<dbname>Authorization:Basic认证,这是一个 Base64 编码的<username>:<password>字符串。更多信息,请参考 鉴权 和 HTTP API。X-Greptime-Log-Table-Name:<table_name>(可选)- 存储日志的表名。如果未提供,默认表名为opentelemetry_logs。X-Greptime-Log-Extract-Keys:<extract_keys>(可选)- 从属性中提取对应 key 的值到表的顶级字段。key 应以逗号(,)分隔。例如,key1,key2,key3将从属性中提取key1、key2和key3,并将它们提升到日志的顶层,设置为标签。如果提取的字段类型是数组、浮点数或对象,将返回错误。如果提供了 pipeline name,此设置将被忽略。X-Greptime-Log-Pipeline-Name:<pipeline_name>(可选)- 处理日志的 pipeline 名称。如果未提供,将使用X-Greptime-Log-Extract-Keys来处理日志。X-Greptime-Log-Pipeline-Version:<pipeline_version>(可选)- 处理日志的 pipeline 的版本。如果未提供,将使用 pipeline 的最新版本。
请求使用二进制 protobuf 编码负载,因此您需要使用支持 HTTP/protobuf 的包。
包名可能会根据 OpenTelemetry 的更新而变化,因此我们建议您参考官方 OpenTelemetry 文档以获取最新信息。
有关 OpenTelemetry SDK 的更多信息,请参考您首选编程语言的官方文档。
示例代码
请参考 opentelemetry-collector 中的示例代码,里面包含了如何将 OpenTelemetry 日志发送到 GreptimeDB。 也可参考 Alloy 文档中的示例代码,了解如何将 OpenTelemetry 日志发送到 GreptimeDB。
数据模型
OTLP 日志数据模型根据以下规则映射到 GreptimeDB 数据模型:
默认表结构:
+-----------------------+---------------------+------+------+---------+---------------+
| Column | Type | Key | Null | Default | Semantic Type |
+-----------------------+---------------------+------+------+---------+---------------+
| timestamp | TimestampNanosecond | PRI | NO | | TIMESTAMP |
| trace_id | String | | YES | | FIELD |
| span_id | String | | YES | | FIELD |
| severity_text | String | | YES | | FIELD |
| severity_number | Int32 | | YES | | FIELD |
| body | String | | YES | | FIELD |
| log_attributes | Json | | YES | | FIELD |
| trace_flags | UInt32 | | YES | | FIELD |
| scope_name | String | PRI | YES | | TAG |
| scope_version | String | | YES | | FIELD |
| scope_attributes | Json | | YES | | FIELD |
| scope_schema_url | String | | YES | | FIELD |
| resource_attributes | Json | | YES | | FIELD |
| resource_schema_url | String | | YES | | FIELD |
+-----------------------+---------------------+------+------+---------+---------------+
17 rows in set (0.00 sec)
- 您可以使用
X-Greptime-Log-Table-Name指定存储日志的表名。如果未提供,默认表名为opentelemetry_logs。 - 所有属性,包括资源属性、范围属性和日志属性,将作为 JSON 列存储在 GreptimeDB 表中。
- 日志的时间戳将用作 GreptimeDB 中的时间戳索引,列名为
timestamp。建议使用time_unix_nano作为时间戳列。如果未提供time_unix_nano,将使用observed_time_unix_nano。
Append 模式
通过此接口创建的表,默认为Append 模式.
Traces
GreptimeDB 支持直接写入 OpenTelemetry 协议的 traces 数据,并内置 OpenTelemetry 的 traces 的表模型来让用户方便地查询和分析 traces 数据。
OTLP/HTTP API
你可以使用 OpenTelemetry SDK 或其他类似的技术方案来为应用添加 traces 数据。你还可以用 OpenTelemetry Collector 来收集 traces 数据,并使用 GreptimeDB 作为后端存储。
要通过 OpenTelemetry SDK 库将 OpenTelemetry 的 traces 数据发送到 GreptimeDB,请使用以下信息:
- URL:
http{s}://<host>/v1/otlp/v1/traces - Headers:
Content-Type: 应配置为application/x-protobufAuthorization:Basic认证。X-Greptime-DB-Name:<dbname>X-Greptime-Trace-Table-Name:<table_name>(可选)- 存储 traces 的表名。如果未提供,默认表名为opentelemetry_traces。X-Greptime-Pipeline-Name:greptime_trace_v1(必选)- 处理 traces 的 pipeline 名称。
GreptimeDB 会通过 HTTP 协议 接受 protobuf 编码的 traces 数据。
示例代码
你可以直接将 OpenTelemetry traces 数据发送到 GreptimeDB,也可以使用 OpenTelemetry Collector 来收集 traces 数据,并使用 GreptimeDB 作为后端存储,请参考 OpenTelemetry Collector 文档中的示例代码,了解如何将 OpenTelemetry traces 数据发送到 GreptimeDB。
数据模型
GreptimeDB 将 OTLP traces 数据模型映射到表结构。默认情况下,Trace 数据存储在 opentelemetry_traces 表中。
+------------------------------------+---------------------+------+------+---------+---------------+
| Column | Type | Key | Null | Default | Semantic Type |
+------------------------------------+---------------------+------+------+---------+---------------+
| timestamp | TimestampNanosecond | PRI | NO | | TIMESTAMP |
| timestamp_end | TimestampNanosecond | | YES | | FIELD |
| duration_nano | UInt64 | | YES | | FIELD |
| parent_span_id | String | | YES | | FIELD |
| trace_id | String | | YES | | FIELD |
| span_id | String | | YES | | FIELD |
| span_kind | String | | YES | | FIELD |
| span_name | String | | YES | | FIELD |
| span_status_code | String | | YES | | FIELD |
| span_status_message | String | | YES | | FIELD |
| trace_state | String | | YES | | FIELD |
| scope_name | String | | YES | | FIELD |
| scope_version | String | | YES | | FIELD |
| service_name | String | PRI | YES | | TAG |
| span_attributes.net.sock.peer.addr | String | | YES | | FIELD |
| span_attributes.peer.service | String | | YES | | FIELD |
| span_events | Json | | YES | | FIELD |
| span_links | Json | | YES | | FIELD |
+------------------------------------+---------------------+------+------+---------+---------------+
- 每一行代表一个单一的 span。
service_name用作 Tag(主键的一部分)。timestamp用作 时间索引(Time Index)。- Resource Attributes 和 Span Attributes 将被自动展平为单独的列。
- 注意:
resource_attributes.service.name被排除在打平之外,因为它已经存储在service_name列中。
- 注意:
span_events和span_links默认存储为JSON数据类型。
有关数据模型和辅助表的更多详细信息,请参阅 Trace 数据模型。
注意:
greptime_trace_v1处理方式默认通过trace_id字段将数据切分成不同的分区以提升性能。请确保trace_id的第一个字符是分布均匀的。- 在非测试的场合下,可以通过设置
ttl以避免持久化数据量过大。通过设置x-greptime-hints: ttl=7dHTTP 请求头,在创建 trace 表时会添加一个 7 天的ttl表选项。见此文档了解更多关于表选项ttl的信息。
辅助表
GreptimeDB 会自动创建辅助表(例如 opentelemetry_traces_services 和 opentelemetry_traces_operations),以便于搜索服务和操作。详情请参阅辅助表。
Append-only 模式
通过此接口创建的表,默认为Append-only 模式。