diff --git a/common/config/clickhouse.go b/common/config/clickhouse.go index 23ee4c756e..3ed3ad5f92 100644 --- a/common/config/clickhouse.go +++ b/common/config/clickhouse.go @@ -2,14 +2,21 @@ package config import ( "errors" + "net/url" + "strings" "github.com/odigos-io/odigos/common" ) const ( - clickhouseEndpoint = "CLICKHOUSE_ENDPOINT" - clickhouseUsername = "CLICKHOUSE_USERNAME" - clickhousePassword = "CLICKHOUSE_PASSWORD" + clickhouseEndpoint = "CLICKHOUSE_ENDPOINT" + clickhouseUsername = "CLICKHOUSE_USERNAME" + clickhousePassword = "${CLICKHOUSE_PASSWORD}" + clickhouseCreateSchema = "CLICKHOUSE_CREATE_SCHEME" + clickhouseDatabaseName = "CLICKHOUSE_DATABASE_NAME" + clickhouseTracesTable = "CLICKHOUSE_TRACES_TABLE" + clickhouseMetricsTable = "CLICKHOUSE_METRICS_TABLE" + clickhouseLogsTable = "CLICKHOUSE_LOGS_TABLE" ) type Clickhouse struct{} @@ -24,19 +31,53 @@ func (c *Clickhouse) ModifyConfig(dest ExporterConfigurer, currentConfig *Config return errors.New("clickhouse endpoint not specified, gateway will not be configured for Clickhouse") } - username, userExists := dest.GetConfig()[clickhouseUsername] - password, passExists := dest.GetConfig()[clickhousePassword] - if userExists != passExists { - return errors.New("clickhouse username and password must be both specified, or neither") + if !strings.Contains(endpoint, "://") { + endpoint = "tcp://" + endpoint + } + + parsedUrl, err := url.Parse(endpoint) + if err != nil { + return errors.New("clickhouse endpoint is not a valid URL") + } + + if parsedUrl.Port() == "" { + endpoint = strings.Replace(endpoint, parsedUrl.Host, parsedUrl.Host+":9000", 1) } + username, userExists := dest.GetConfig()[clickhouseUsername] + exporterName := "clickhouse/clickhouse-" + dest.GetID() exporterConfig := GenericMap{ "endpoint": endpoint, } if userExists { exporterConfig["username"] = username - exporterConfig["password"] = password + exporterConfig["password"] = clickhousePassword + } + + createSchema, exists := dest.GetConfig()[clickhouseCreateSchema] + createSchemaBoolValue := exists && strings.ToLower(createSchema) == "create" + exporterConfig["create_schema"] = createSchemaBoolValue + + dbName, exists := dest.GetConfig()[clickhouseDatabaseName] + if !exists { + return errors.New("clickhouse database name not specified, gateway will not be configured for Clickhouse") + } + exporterConfig["database"] = dbName + + tracesTable, exists := dest.GetConfig()[clickhouseTracesTable] + if exists { + exporterConfig["traces_table_name"] = tracesTable + } + + metricsTable, exists := dest.GetConfig()[clickhouseMetricsTable] + if exists { + exporterConfig["metrics_table_name"] = metricsTable + } + + logsTable, exists := dest.GetConfig()[clickhouseLogsTable] + if exists { + exporterConfig["logs_table_name"] = logsTable } currentConfig.Exporters[exporterName] = exporterConfig diff --git a/destinations/data/clickhouse.yaml b/destinations/data/clickhouse.yaml index 8b4542c812..5eac44faff 100644 --- a/destinations/data/clickhouse.yaml +++ b/destinations/data/clickhouse.yaml @@ -29,7 +29,44 @@ spec: - name: CLICKHOUSE_PASSWORD displayName: Password componentType: input + secret: true componentProps: type: password required: false - secret: true + - name: CLICKHOUSE_CREATE_SCHEME + displayName: Create Scheme + componentType: dropdown + componentProps: + values: + - Create + - Skip + required: true + initialValue: Create + - name: CLICKHOUSE_DATABASE_NAME + displayName: Database Name + componentType: input + componentProps: + type: text + required: true + initialValue: otel + - name: CLICKHOUSE_TRACES_TABLE + displayName: Traces Table + componentType: input + componentProps: + type: text + required: true + initialValue: otel_traces + - name: CLICKHOUSE_METRICS_TABLE + displayName: Metrics Table + componentType: input + componentProps: + type: text + required: true + initialValue: otel_metrics + - name: CLICKHOUSE_LOGS_TABLE + displayName: Logs Table + componentType: input + componentProps: + type: text + required: true + initialValue: otel_logs \ No newline at end of file