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 中,可以使用 @opentelemetry/exporter-metrics-otlp-proto;在 Go 中,可以使用 go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp;在 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)
关于示例代码,请参考 Opentelementry 的官方文档获取它所支持的编程语言获取更多信息。
兼容 Prometheus
GreptimeDB 支持以 Prometheus 兼容模式写入 OTLP 指标。 如果指标以这种兼容模式写入,你可以像查询 Prometheus 原生指标一样使用 PromQL 直接查询这些指标。
GreptimeDB 会为每个 OTLP 导出请求统一选择写入格式:
- 如果请求涉及的指标表都不存在,GreptimeDB 使用 Prometheus 兼容格式。
- 如果请求涉及的已有表都使用同一种格式,GreptimeDB 对请求中的所有指标使用该格式,包括由该请求新建的表。
- 如果请求同时涉及两种格式的已有表,GreptimeDB 会拒绝该请求。
如需同时写入旧格式和 Prometheus 兼容格式的指标,请将它们拆分到不同的 OTLP 导出请求中。
GreptimeDB 会首先对数据进行预处理,包括:
-
将指标名(表名)和标签名转换成 Prometheus 风格的命名(例如:将
.替换为_)。默认情况下,GreptimeDB 还会根据指标单位和类型添加 Prometheus 风格的后缀。具体信息请参考这里以下是一些转换示例:
OTLP 指标 / 属性 OTLP 类型 / 单位 Prometheus 等效名称 cache.hit_ratioGauge / 1cache_hit_ratiomemory.usageGauge / Bymemory_usage_bytesqueue.lengthGauge / {item}queue_lengthhttp.server.request.durationHistogram / shttp_server_request_duration_secondsrpc.server.durationHistogram / msrpc_server_duration_millisecondshttp.client.request.sizeSum (Monotonic) / Byhttp_client_request_size_bytes_totalsystem.network.ioSum (Monotonic) / Bysystem_network_io_bytes_totalhttp.status_code(属性)- http_status_codeservice.name(属性)- service_name -
默认丢弃一些 resource 属性和全部的 scope 属性。默认保存的 resource 属性列表可以参考这里。你可以通过配置项对这个行为进行调整
注意: OTLP 的 Sum 和 Histogram 指标的数据可能是增量时序(delta temporality)类型的。
GreptimeDB 将会直接保存它们,不会进行累计值(cumulative value)的计算。
参考这里获取更多背景信息。
你可以通过设置 HTTP 请求头来调整预处理的行为。以下是选项列表:
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。x-greptime-otlp-metric-translation-strategy: 在保存前如何转换 OTLP 指标名(表名)和标签名(tag 列)。默认是UnderscoreEscapingWithSuffixes。
x-greptime-otlp-metric-translation-strategy 请求头支持以下取值:
| 取值 | 指标名行为 | 标签名行为 | 原始名称 | 转换后名称 |
|---|---|---|---|---|
UnderscoreEscapingWithSuffixes | 将不支持的字符转换为 _,并添加 Prometheus 风格的 单位和类型后缀。 | 将不支持的字符转换为 _。 | 指标:http.server.request-duration_total(monotonic sum,单位 ms)标签: _http.status-code | 指标:http_server_request_duration_milliseconds_total标签: key_http_status_code |
UnderscoreEscapingWithoutSuffixes | 将不支持的字符转换为 _,但不添加单位和类型后缀。 | 将不支持的字符转换为 _。 | 指标:http.server.request-duration_total(monotonic sum,单位 ms)标签: _http.status-code | 指标:http_server_request_duration_total标签: key_http_status_code |
NoUTF8EscapingWithSuffixes | 保留指标名中的原始字符,并添加 Prometheus 风格的单位和类型后缀。 | 保留标签名中的原始字符。 | 指标:http.server.request-duration_total(monotonic sum,单位 ms)标签: _http.status-code | 指标:http.server.request-duration_milliseconds_total标签: _http.status-code |
NoTranslation | 保留原始指标名,并且不添加后缀。 | 保留标签名中的原始字符。 | 指标:http.server.request-duration_total(monotonic sum,单位 ms)标签: _http.status-code | 指标:http.server.request-duration_total标签: _http.status-code |
请求头取值区分大小写。无效取值会被拒绝,并返回 400 Bad Request。
更多信息请参考 OTel 规范和 Prometheus 文档。
数据模型
兼容 Prometheus 的 OTLP 指标数据模型按照下方的规则被映射到 GreptimeDB 数据模型中:
- Metric 的名称将被作为 GreptimeDB 表的名称,当表不存在时会自动创建。
- 只有特定 resource 属性会被默认保留。详情和配置选项见上一小节。属性在 GreptimeDB 表中会被作为 tag 列。
- 参考 Prometheus 数据模型了解更多数据模型信息。
- 默认支持通过 OTLP/HTTP 写入累积(cumulative temporality)的
ExponentialHistogram指标。 每个数据点以原生直方图的形式存储在 Struct 字段中,字段名默认为greptime_native_histogram, 而不是拆分为_bucket、_sum和_count序列。增量时序(delta temporality)和未指定时序的指标会被拒绝。
无效的指数直方图数据点会被拒绝,同一 OTLP/HTTP 请求中的有效数据点仍可写入。
这类请求返回部分成功;如果请求中只有被拒绝的数据点,则返回 InvalidArgument 错误。
OTel Arrow 的传输格式缺少 zero_threshold,因此不支持指数直方图。
如果某张表是由旧版 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,并将它们提升到日志的顶层,设置为标签。key 匹配不区分大小写。如果同一个 key 同时存在于 log attributes、scope attributes 和 resource attributes 中,优先使用 log attributes 的值,其次是 scope attributes,最后是 resource attributes。可提取的值类型包括字符串、有符号整数、无符号整数和布尔值。如果提取的字段类型是数组、浮点数或对象,将返回错误。如果提供了 pipeline name,此设置将被忽略。X-Greptime-Pipeline-Name:<pipeline_name>(可选)- 处理日志的 pipeline 名称。如果未提供,GreptimeDB 使用内置的 OTLP 日志映射,并在提供X-Greptime-Log-Extract-Keys时应用该配置。X-Greptime-Pipeline-Version:<pipeline_version>(可选)- 处理日志的 pipeline 版本。如果未提供,将使用 pipeline 的最新版本。X-Greptime-Pipeline-Params:<pipeline_params>(可选)- 使用自定义 pipeline 处理日志时传入的 pipeline 参数。
X-Greptime-Log-Pipeline-Name 和 X-Greptime-Log-Pipeline-Version 也可以作为通用 pipeline header 的旧别名使用。新的配置建议使用 X-Greptime-Pipeline-Name 和 X-Greptime-Pipeline-Version。
请求使用二进制 protobuf 编码负载,因此您需要使用支持 HTTP/protobuf 的包。
包名可能会根据 OpenTelemetry 的更新而变化,因此我们建议您参考官方 OpenTelemetry 文档以获取最新信息。
有关 OpenTelemetry SDK 的更多信息,请参考您首选编程语言的官方文档。
示例代码
请参考 OpenTelemetry Collector 文档中的示例代码,里面包含了如何将 OpenTelemetry 日志发送到 GreptimeDB。 也可参考 Alloy 文档中的示例代码,了解如何将 OpenTelemetry 日志发送到 GreptimeDB。
自定义 Pipeline 输入
当设置了 X-Greptime-Pipeline-Name 时,GreptimeDB 会把每条 OTLP 日志记录转换成一个 pipeline event。event 包含以下字段:
| 字段 | 说明 |
|---|---|
Timestamp | OTLP 的 time_unix_nano。 |
ObservedTimestamp | OTLP 的 observed_time_unix_nano。 |
TraceId、SpanId | 十六进制编码后的 ID。 |
TraceFlags、SeverityText、SeverityNumber、Body | 对应的 OTLP 日志字段。Body 会被转换成字符串。 |
ResourceSchemaUrl、ScopeSchemaUrl、ScopeName、ScopeVersion | 对应的 resource 和 scope 字段。 |
ResourceAttributes、ScopeAttributes、LogAttributes | 包含对应 OTLP attributes 的对象。 |
数据模型
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 | Int32 | | 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 |
+-----------------------+---------------------+------+------+---------+---------------+
14 rows in set (0.00 sec)
- 您可以使用
X-Greptime-Log-Table-Name指定存储日志的表名。如果未提供,默认表名为opentelemetry_logs。 - 所有属性,包括资源属性、范围属性和日志属性,将作为 JSON 列存储在 GreptimeDB 表中。
body列默认会创建 fulltext 索引。该索引使用默认的全文索引配置:analyzer=English、case_sensitive=false和backend=bloom。对于 Bloom 后端,默认的granularity为10240,默认的false_positive_rate为0.01。更多信息请参考全文索引文档。- 日志的时间戳将用作 GreptimeDB 中的时间戳索引,列名为
timestamp。建议使用time_unix_nano作为时间戳列。如果未提供time_unix_nano,将使用observed_time_unix_nano。
Append-only 模式
通过此接口创建的表,默认为Append-only 模式。
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 数据