-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[exporter/doris] New component: Doris Exporter (#33790)
First PR of New component: Doris Exporter. **Link to tracking Issue:** #33479
- Loading branch information
1 parent
5612c15
commit ec83b46
Showing
21 changed files
with
797 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
# Use this changelog template to create an entry for release notes. | ||
|
||
# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' | ||
change_type: new_component | ||
|
||
# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver) | ||
component: exporter/doris | ||
|
||
# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). | ||
note: "Add a new component for exporting logs, traces and metrics to Doris" | ||
|
||
# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. | ||
issues: [33479] | ||
|
||
# (Optional) One or more lines of additional information to render under the primary note. | ||
# These lines will be padded with 2 spaces and then inserted directly into the document. | ||
# Use pipe (|) for multiline entries. | ||
subtext: | ||
|
||
# If your change doesn't affect end users or the exported elements of any package, | ||
# you should instead start your pull request title with [chore] or use the "Skip Changelog" label. | ||
# Optional: The change log or logs in which this entry should be included. | ||
# e.g. '[user]' or '[user, api]' | ||
# Include 'user' if the change is relevant to end users. | ||
# Include 'api' if there is a change to a library API. | ||
# Default: '[user]' | ||
change_logs: [user] |
Validating CODEOWNERS rules …
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,3 +22,4 @@ tomasmota | |
m1rp | ||
jriguera | ||
abhishek-at-cloudwerx | ||
joker-star-l |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
include ../../Makefile.Common | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
# Apache Doris Exporter | ||
<!-- status autogenerated section --> | ||
| Status | | | ||
| ------------- |-----------| | ||
| Stability | [development]: traces, metrics, logs | | ||
| Distributions | [] | | ||
| Issues | [![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aexporter%2Fdoris%20&label=open&color=orange&logo=opentelemetry)](https://github.com/open-telemetry/opentelemetry-collector-contrib/issues?q=is%3Aopen+is%3Aissue+label%3Aexporter%2Fdoris) [![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aexporter%2Fdoris%20&label=closed&color=blue&logo=opentelemetry)](https://github.com/open-telemetry/opentelemetry-collector-contrib/issues?q=is%3Aclosed+is%3Aissue+label%3Aexporter%2Fdoris) | | ||
| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@atoulme](https://www.github.com/atoulme), [@joker-star-l](https://www.github.com/joker-star-l) | | ||
|
||
[development]: https://github.com/open-telemetry/opentelemetry-collector#development | ||
<!-- end autogenerated section --> | ||
|
||
This exporter supports sending traces, metrics, and logs data to [Apache Doris](https://doris.apache.org/) (version >= 2.1). | ||
|
||
## Configuration | ||
|
||
The following configuration options are supported: | ||
|
||
* `endpoint` The http stream load address. | ||
* `database` (default = otel) The database name. | ||
* `username` The authentication username. | ||
* `password` The authentication password. | ||
* `table` | ||
* `logs` (default = otel_logs) The table name for logs. | ||
* `traces` (default = otel_traces) The table name for traces. | ||
* `metrics` (default = otel_metrics) The table name for metrics. | ||
* `create_schema` (default = true) Whether databases and tables are created automatically. | ||
* `mysql_endpoint` The mysql protocol address to create the schema; ignored if `create_schema` is false. | ||
* `history_days` (default = 0) Data older than these days will be deleted; ignored if `create_schema` is false. If set to 0, historical data will not be deleted. | ||
* `create_history_days` (default = 0) The number of days in the history partition that was created when the table was created; ignored if `create_schema` is false. If `history_days` is not 0, `create_history_days` needs to be less than or equal to `history_days`. | ||
* `replication_num` (default = 1) The number of replicas of the table; ignored if `create_schema` is false. | ||
* `timezone` (default is the time zone of the opentelemetry collector) The time zone of doris. | ||
* `timeout` (default = 5s) Time to wait per individual attempt to send data to a backend. | ||
* `sending_queue` [details here](https://github.com/open-telemetry/opentelemetry-collector/tree/main/exporter/exporterhelper#configuration) | ||
* `enabled` (default = true) | ||
* `num_consumers` (default = 10) Number of consumers that dequeue batches; ignored if `enabled` is false. | ||
* `queue_size` (default = 1000) Maximum number of batches kept in memory before dropping; ignored if `enabled` is false. | ||
* `retry_on_failure` [details here](https://github.com/open-telemetry/opentelemetry-collector/tree/main/exporter/exporterhelper#configuration) | ||
* `enabled` (default = true) | ||
* `initial_interval` (default = 5s) Time to wait after the first failure before retrying; ignored if `enabled` is false. | ||
* `max_interval` (default = 30s) The upper bound on backoff; ignored if `enabled` is false. | ||
* `max_elapsed_time` (default = 300s) The maximum amount of time spent trying to send a batch; ignored if `enabled` is false. If set to 0, the retries are never stopped. | ||
|
||
Example: | ||
```yaml | ||
exporters: | ||
doris: | ||
endpoint: http://localhost:8030 | ||
database: otel | ||
username: admin | ||
password: admin | ||
table: | ||
logs: otel_logs | ||
traces: otel_traces | ||
metrics: otel_metrics | ||
create_schema: true | ||
mysql_endpoint: localhost:9030 | ||
history_days: 0 | ||
create_history_days: 0 | ||
replication_num: 1 | ||
timezone: Asia/Shanghai | ||
timeout: 5s | ||
sending_queue: | ||
enabled: true | ||
num_consumers: 10 | ||
queue_size: 1000 | ||
retry_on_failure: | ||
enabled: true | ||
initial_interval: 5s | ||
max_interval: 30s | ||
max_elapsed_time: 300s | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
// Copyright The OpenTelemetry Authors | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package dorisexporter // import "github.com/open-telemetry/opentelemetry-collector-contrib/exporter/dorisexporter" | ||
|
||
import ( | ||
"errors" | ||
"regexp" | ||
|
||
"go.opentelemetry.io/collector/config/configopaque" | ||
"go.opentelemetry.io/collector/config/configretry" | ||
"go.opentelemetry.io/collector/exporter/exporterhelper" | ||
) | ||
|
||
type Config struct { | ||
exporterhelper.TimeoutSettings `mapstructure:",squash"` | ||
configretry.BackOffConfig `mapstructure:"retry_on_failure"` | ||
exporterhelper.QueueSettings `mapstructure:"sending_queue"` | ||
|
||
// TableNames is the table name for logs, traces and metrics. | ||
Table `mapstructure:"table"` | ||
|
||
// Endpoint is the http stream load address. | ||
Endpoint string `mapstructure:"endpoint"` | ||
// Database is the database name. | ||
Database string `mapstructure:"database"` | ||
// Username is the authentication username. | ||
Username string `mapstructure:"username"` | ||
// Password is the authentication password. | ||
Password configopaque.String `mapstructure:"password"` | ||
// CreateSchema is whether databases and tables are created automatically. | ||
CreateSchema bool `mapstructure:"create_schema"` | ||
// MySQLEndpoint is the mysql protocol address to create the schema; ignored if create_schema is false. | ||
MySQLEndpoint string `mapstructure:"mysql_endpoint"` | ||
// Data older than these days will be deleted; ignored if create_schema is false. If set to 0, historical data will not be deleted. | ||
HistoryDays int32 `mapstructure:"history_days"` | ||
// The number of days in the history partition that was created when the table was created; ignored if create_schema is false. | ||
// If history_days is not 0, create_history_days needs to be less than or equal to history_days. | ||
CreateHistoryDays int32 `mapstructure:"create_history_days"` | ||
// ReplicationNum is the number of replicas of the table; ignored if create_schema is false. | ||
ReplicationNum int32 `mapstructure:"replication_num"` | ||
// Timezone is the timezone of the doris. | ||
TimeZone string `mapstructure:"timezone"` | ||
} | ||
|
||
type Table struct { | ||
// Logs is the table name for logs. | ||
Logs string `mapstructure:"logs"` | ||
// Traces is the table name for traces. | ||
Traces string `mapstructure:"traces"` | ||
// Metrics is the table name for metrics. | ||
Metrics string `mapstructure:"metrics"` | ||
} | ||
|
||
func (cfg *Config) Validate() (err error) { | ||
if cfg.Endpoint == "" { | ||
err = errors.Join(err, errors.New("endpoint must be specified")) | ||
} | ||
if cfg.CreateSchema { | ||
if cfg.MySQLEndpoint == "" { | ||
err = errors.Join(err, errors.New("mysql_endpoint must be specified")) | ||
} | ||
|
||
if cfg.HistoryDays < 0 { | ||
err = errors.Join(err, errors.New("history_days must be greater than or equal to 0")) | ||
} | ||
|
||
if cfg.CreateHistoryDays < 0 { | ||
err = errors.Join(err, errors.New("create_history_days must be greater than or equal to 0")) | ||
} | ||
|
||
if cfg.HistoryDays > 0 && cfg.CreateHistoryDays > cfg.HistoryDays { | ||
err = errors.Join(err, errors.New("create_history_days must be less than or equal to history_days")) | ||
} | ||
|
||
if cfg.ReplicationNum < 1 { | ||
err = errors.Join(err, errors.New("replication_num must be greater than or equal to 1")) | ||
} | ||
} | ||
|
||
// Preventing SQL Injection Attacks | ||
re := regexp.MustCompile(`^[a-zA-Z0-9_]+$`) | ||
if !re.MatchString(cfg.Database) { | ||
err = errors.Join(err, errors.New("database name must be alphanumeric and underscore")) | ||
} | ||
if !re.MatchString(cfg.Table.Logs) { | ||
err = errors.Join(err, errors.New("logs table name must be alphanumeric and underscore")) | ||
} | ||
if !re.MatchString(cfg.Table.Traces) { | ||
err = errors.Join(err, errors.New("traces table name must be alphanumeric and underscore")) | ||
} | ||
if !re.MatchString(cfg.Table.Metrics) { | ||
err = errors.Join(err, errors.New("metrics table name must be alphanumeric and underscore")) | ||
} | ||
|
||
return err | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
// Copyright The OpenTelemetry Authors | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package dorisexporter // import "github.com/open-telemetry/opentelemetry-collector-contrib/exporter/dorisexporter" | ||
|
||
import ( | ||
"path/filepath" | ||
"testing" | ||
"time" | ||
|
||
"github.com/cenkalti/backoff/v4" | ||
"github.com/stretchr/testify/assert" | ||
"github.com/stretchr/testify/require" | ||
"go.opentelemetry.io/collector/component" | ||
"go.opentelemetry.io/collector/config/configopaque" | ||
"go.opentelemetry.io/collector/config/configretry" | ||
"go.opentelemetry.io/collector/confmap/confmaptest" | ||
"go.opentelemetry.io/collector/exporter/exporterhelper" | ||
|
||
"github.com/open-telemetry/opentelemetry-collector-contrib/exporter/dorisexporter/internal/metadata" | ||
) | ||
|
||
func TestLoadConfig(t *testing.T) { | ||
t.Parallel() | ||
|
||
cm, err := confmaptest.LoadConf(filepath.Join("testdata", "config.yaml")) | ||
require.NoError(t, err) | ||
|
||
defaultCfg := createDefaultConfig() | ||
defaultCfg.(*Config).Endpoint = "http://localhost:8030" | ||
defaultCfg.(*Config).MySQLEndpoint = "localhost:9030" | ||
|
||
tests := []struct { | ||
id component.ID | ||
expected component.Config | ||
}{ | ||
{ | ||
id: component.NewIDWithName(metadata.Type, ""), | ||
expected: defaultCfg, | ||
}, | ||
{ | ||
id: component.NewIDWithName(metadata.Type, "full"), | ||
expected: &Config{ | ||
TimeoutSettings: exporterhelper.TimeoutSettings{Timeout: 5 * time.Second}, | ||
BackOffConfig: configretry.BackOffConfig{ | ||
Enabled: true, | ||
InitialInterval: 5 * time.Second, | ||
MaxInterval: 30 * time.Second, | ||
MaxElapsedTime: 300 * time.Second, | ||
RandomizationFactor: backoff.DefaultRandomizationFactor, | ||
Multiplier: backoff.DefaultMultiplier, | ||
}, | ||
QueueSettings: exporterhelper.QueueSettings{ | ||
Enabled: true, | ||
NumConsumers: 10, | ||
QueueSize: 1000, | ||
}, | ||
Table: Table{ | ||
Logs: "otel_logs", | ||
Traces: "otel_traces", | ||
Metrics: "otel_metrics", | ||
}, | ||
Endpoint: "http://localhost:8030", | ||
Database: "otel", | ||
Username: "admin", | ||
Password: configopaque.String("admin"), | ||
CreateSchema: true, | ||
MySQLEndpoint: "localhost:9030", | ||
HistoryDays: 0, | ||
CreateHistoryDays: 0, | ||
ReplicationNum: 2, | ||
TimeZone: "Asia/Shanghai", | ||
}, | ||
}, | ||
} | ||
|
||
for _, tt := range tests { | ||
t.Run(tt.id.String(), func(t *testing.T) { | ||
factory := NewFactory() | ||
cfg := factory.CreateDefaultConfig() | ||
|
||
sub, err := cm.Sub(tt.id.String()) | ||
require.NoError(t, err) | ||
require.NoError(t, sub.Unmarshal(cfg)) | ||
|
||
assert.NoError(t, component.ValidateConfig(cfg)) | ||
assert.Equal(t, tt.expected, cfg) | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
// Copyright The OpenTelemetry Authors | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
//go:generate mdatagen metadata.yaml | ||
|
||
// Package dorisexporter exports trace, metric and log data to an Apache Doris instance. | ||
package dorisexporter // import "github.com/open-telemetry/opentelemetry-collector-contrib/exporter/dorisexporter" |
Oops, something went wrong.