mirror of
https://github.com/hyperdxio/hyperdx
synced 2026-04-21 13:37:15 +00:00
feat: add TLS support for OTel collector migration script (#1714)
Moved the inline goose CLI script to its own go script. For the seed DDLs, we don’t create the version tables, and they should all be idempotent.
This commit is contained in:
parent
a33efbc4b5
commit
baf18da4c0
16 changed files with 627 additions and 124 deletions
5
.changeset/red-walls-rescue.md
Normal file
5
.changeset/red-walls-rescue.md
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
"@hyperdx/otel-collector": patch
|
||||
---
|
||||
|
||||
feat: add TLS support for OTel collector migration script
|
||||
5
.changeset/slow-ears-yawn.md
Normal file
5
.changeset/slow-ears-yawn.md
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
"@hyperdx/otel-collector": patch
|
||||
---
|
||||
|
||||
chore: bump otel collector version to v0.136.0
|
||||
|
|
@ -2,7 +2,8 @@ name: hdx-ci
|
|||
services:
|
||||
otel-collector:
|
||||
build:
|
||||
context: ./docker/otel-collector
|
||||
context: .
|
||||
dockerfile: docker/otel-collector/Dockerfile
|
||||
target: dev
|
||||
environment:
|
||||
CLICKHOUSE_ENDPOINT: 'tcp://ch-server:9000?dial_timeout=10s'
|
||||
|
|
|
|||
|
|
@ -22,7 +22,8 @@ services:
|
|||
otel-collector:
|
||||
# image: otel/opentelemetry-collector-contrib:0.120.0
|
||||
build:
|
||||
context: ./docker/otel-collector
|
||||
context: .
|
||||
dockerfile: docker/otel-collector/Dockerfile
|
||||
target: dev
|
||||
environment:
|
||||
CLICKHOUSE_ENDPOINT: 'tcp://ch-server:9000?dial_timeout=10s'
|
||||
|
|
@ -54,7 +55,8 @@ services:
|
|||
otel-collector-json:
|
||||
# image: otel/opentelemetry-collector-contrib:0.120.0
|
||||
build:
|
||||
context: ./docker/otel-collector
|
||||
context: .
|
||||
dockerfile: docker/otel-collector/Dockerfile
|
||||
target: dev
|
||||
environment:
|
||||
CLICKHOUSE_ENDPOINT: 'tcp://ch-server:9000?dial_timeout=10s'
|
||||
|
|
|
|||
|
|
@ -9,8 +9,8 @@
|
|||
|
||||
ARG NODE_VERSION=22.16.0
|
||||
ARG CLICKHOUSE_VERSION=25.6
|
||||
ARG OTEL_COLLECTOR_VERSION=0.129.1
|
||||
ARG OTEL_COLLECTOR_OPAMPSUPERVISOR_VERSION=0.128.0
|
||||
ARG OTEL_COLLECTOR_VERSION=0.136.0
|
||||
ARG OTEL_COLLECTOR_OPAMPSUPERVISOR_VERSION=0.136.0
|
||||
|
||||
# base #############################################################################################
|
||||
# == Otel Collector Image ==
|
||||
|
|
@ -18,6 +18,14 @@ FROM otel/opentelemetry-collector-contrib:${OTEL_COLLECTOR_VERSION} AS otel_coll
|
|||
FROM otel/opentelemetry-collector-opampsupervisor:${OTEL_COLLECTOR_OPAMPSUPERVISOR_VERSION} AS otel_collector_opampsupervisor_base
|
||||
FROM kukymbr/goose-docker@sha256:0cd025636df126e7f66472861ca4db3683bc649be46cd1f6ef1a316209058e23 AS goose
|
||||
|
||||
# Build the Go migration tool with full TLS support for ClickHouse
|
||||
FROM golang:1.25-alpine AS migrate-builder
|
||||
WORKDIR /build
|
||||
COPY packages/otel-collector/go.mod packages/otel-collector/go.sum ./
|
||||
RUN go mod download
|
||||
COPY packages/otel-collector/ ./
|
||||
RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-s -w" -o /migrate ./cmd/migrate
|
||||
|
||||
FROM node:${NODE_VERSION}-alpine AS node_base
|
||||
|
||||
WORKDIR /app
|
||||
|
|
@ -131,6 +139,9 @@ COPY --from=gomplate /bin/gomplate /usr/local/bin/gomplate
|
|||
# Copy goose binary from the goose image
|
||||
COPY --from=goose /bin/goose /usr/local/bin/goose
|
||||
|
||||
# Copy migrate binary (Go-based goose migration tool with full TLS support)
|
||||
COPY --from=migrate-builder /migrate /usr/local/bin/migrate
|
||||
|
||||
# Install MongoDB and other dependencies (consolidated into a single RUN command)
|
||||
RUN echo 'http://dl-cdn.alpinelinux.org/alpine/v3.9/main' >> /etc/apk/repositories && \
|
||||
echo 'http://dl-cdn.alpinelinux.org/alpine/v3.9/community' >> /etc/apk/repositories && \
|
||||
|
|
|
|||
|
|
@ -1,9 +1,18 @@
|
|||
## base #############################################################################################
|
||||
FROM otel/opentelemetry-collector-contrib:0.129.1 AS col
|
||||
FROM otel/opentelemetry-collector-opampsupervisor:0.128.0 AS supervisor
|
||||
FROM otel/opentelemetry-collector-contrib:0.136.0 AS col
|
||||
FROM otel/opentelemetry-collector-opampsupervisor:0.136.0 AS supervisor
|
||||
FROM hairyhenderson/gomplate:v4.3.3-alpine AS gomplate
|
||||
FROM kukymbr/goose-docker@sha256:0cd025636df126e7f66472861ca4db3683bc649be46cd1f6ef1a316209058e23 AS goose
|
||||
|
||||
# Build the Go migration tool with full TLS support for ClickHouse
|
||||
# Note: Build context must be repo root (use: docker build -f docker/otel-collector/Dockerfile .)
|
||||
FROM golang:1.25-alpine AS migrate-builder
|
||||
WORKDIR /build
|
||||
COPY packages/otel-collector/go.mod packages/otel-collector/go.sum ./
|
||||
RUN go mod download
|
||||
COPY packages/otel-collector/ ./
|
||||
RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-s -w" -o /migrate ./cmd/migrate
|
||||
|
||||
# From: https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/aa5c3aa4c7ec174361fcaf908de8eaca72263078/cmd/opampsupervisor/Dockerfile#L18
|
||||
FROM alpine:latest@sha256:a8560b36e8b8210634f77d9f7f9efd7ffa463e380b75e2e74aff4511df3ef88c AS base
|
||||
|
||||
|
|
@ -20,32 +29,35 @@ RUN apk add --no-cache ca-certificates && \
|
|||
# Copy gomplate binary from the gomplate image
|
||||
COPY --from=gomplate /bin/gomplate /usr/local/bin/gomplate
|
||||
|
||||
# Copy goose binary from the goose image
|
||||
# Copy goose binary for shell-based migrations (default)
|
||||
COPY --from=goose /bin/goose /usr/local/bin/goose
|
||||
|
||||
# Copy migrate binary (Go-based goose migration tool with full TLS support)
|
||||
COPY --from=migrate-builder /migrate /usr/local/bin/migrate
|
||||
|
||||
USER ${USER_UID}:${USER_GID}
|
||||
|
||||
COPY --from=supervisor --chmod=755 /usr/local/bin/opampsupervisor /opampsupervisor
|
||||
COPY --from=col --chmod=755 /otelcol-contrib /otelcontribcol
|
||||
|
||||
# Copy entrypoint and log tail wrapper scripts
|
||||
COPY --chmod=755 ./entrypoint.sh /entrypoint.sh
|
||||
COPY --chmod=755 ./log-tailer.sh /log-tailer.sh
|
||||
COPY --chmod=755 docker/otel-collector/entrypoint.sh /entrypoint.sh
|
||||
COPY --chmod=755 docker/otel-collector/log-tailer.sh /log-tailer.sh
|
||||
|
||||
## dev ##############################################################################################
|
||||
FROM base AS dev
|
||||
|
||||
LABEL org.opencontainers.image.vendor="HyperDX" \
|
||||
org.opencontainers.image.title="HyperDX OTel Collector (Dev)" \
|
||||
org.opencontainers.image.description="OpenTelemetry Collector for HyperDX development" \
|
||||
org.opencontainers.image.source="https://github.com/hyperdxio/hyperdx" \
|
||||
org.opencontainers.image.licenses="MIT"
|
||||
org.opencontainers.image.title="HyperDX OTel Collector (Dev)" \
|
||||
org.opencontainers.image.description="OpenTelemetry Collector for HyperDX development" \
|
||||
org.opencontainers.image.source="https://github.com/hyperdxio/hyperdx" \
|
||||
org.opencontainers.image.licenses="MIT"
|
||||
|
||||
COPY --chown=10001:10001 ./config.yaml /etc/otelcol-contrib/config.yaml
|
||||
COPY --chown=10001:10001 ./config.standalone.yaml /etc/otelcol-contrib/standalone-config.yaml
|
||||
COPY --chown=10001:10001 ./config.standalone.auth.yaml /etc/otelcol-contrib/standalone-auth-config.yaml
|
||||
COPY --chown=10001:10001 ./supervisor_docker.yaml.tmpl /etc/otel/supervisor.yaml.tmpl
|
||||
COPY --chown=10001:10001 ./schema /etc/otel/schema
|
||||
COPY --chown=10001:10001 docker/otel-collector/config.yaml /etc/otelcol-contrib/config.yaml
|
||||
COPY --chown=10001:10001 docker/otel-collector/config.standalone.yaml /etc/otelcol-contrib/standalone-config.yaml
|
||||
COPY --chown=10001:10001 docker/otel-collector/config.standalone.auth.yaml /etc/otelcol-contrib/standalone-auth-config.yaml
|
||||
COPY --chown=10001:10001 docker/otel-collector/supervisor_docker.yaml.tmpl /etc/otel/supervisor.yaml.tmpl
|
||||
COPY --chown=10001:10001 docker/otel-collector/schema /etc/otel/schema
|
||||
|
||||
EXPOSE 4317 4318 13133
|
||||
|
||||
|
|
@ -55,16 +67,16 @@ ENTRYPOINT ["/entrypoint.sh", "/opampsupervisor"]
|
|||
FROM base AS prod
|
||||
|
||||
LABEL org.opencontainers.image.vendor="HyperDX" \
|
||||
org.opencontainers.image.title="HyperDX OTel Collector" \
|
||||
org.opencontainers.image.description="OpenTelemetry Collector for HyperDX observability platform" \
|
||||
org.opencontainers.image.source="https://github.com/hyperdxio/hyperdx" \
|
||||
org.opencontainers.image.licenses="MIT"
|
||||
org.opencontainers.image.title="HyperDX OTel Collector" \
|
||||
org.opencontainers.image.description="OpenTelemetry Collector for HyperDX observability platform" \
|
||||
org.opencontainers.image.source="https://github.com/hyperdxio/hyperdx" \
|
||||
org.opencontainers.image.licenses="MIT"
|
||||
|
||||
COPY --chown=10001:10001 ./config.yaml /etc/otelcol-contrib/config.yaml
|
||||
COPY --chown=10001:10001 ./config.standalone.yaml /etc/otelcol-contrib/standalone-config.yaml
|
||||
COPY --chown=10001:10001 ./config.standalone.auth.yaml /etc/otelcol-contrib/standalone-auth-config.yaml
|
||||
COPY --chown=10001:10001 ./supervisor_docker.yaml.tmpl /etc/otel/supervisor.yaml.tmpl
|
||||
COPY --chown=10001:10001 ./schema /etc/otel/schema
|
||||
COPY --chown=10001:10001 docker/otel-collector/config.yaml /etc/otelcol-contrib/config.yaml
|
||||
COPY --chown=10001:10001 docker/otel-collector/config.standalone.yaml /etc/otelcol-contrib/standalone-config.yaml
|
||||
COPY --chown=10001:10001 docker/otel-collector/config.standalone.auth.yaml /etc/otelcol-contrib/standalone-auth-config.yaml
|
||||
COPY --chown=10001:10001 docker/otel-collector/supervisor_docker.yaml.tmpl /etc/otel/supervisor.yaml.tmpl
|
||||
COPY --chown=10001:10001 docker/otel-collector/schema /etc/otel/schema
|
||||
|
||||
EXPOSE 4317 4318 13133
|
||||
|
||||
|
|
|
|||
|
|
@ -3,101 +3,15 @@ set -e
|
|||
|
||||
# Run ClickHouse schema migrations if not using legacy schema creation
|
||||
if [ "$HYPERDX_OTEL_EXPORTER_CREATE_LEGACY_SCHEMA" != "true" ]; then
|
||||
echo "========================================"
|
||||
echo "Running ClickHouse schema migrations..."
|
||||
echo "========================================"
|
||||
|
||||
# Set connection defaults
|
||||
DB_NAME="${HYPERDX_OTEL_EXPORTER_CLICKHOUSE_DATABASE:-default}"
|
||||
DB_USER="${CLICKHOUSE_USER:-default}"
|
||||
DB_PASSWORD="${CLICKHOUSE_PASSWORD:-}"
|
||||
echo "Target database: $DB_NAME"
|
||||
|
||||
# Build goose connection string from environment variables
|
||||
# CLICKHOUSE_ENDPOINT format: tcp://host:port, http://host:port, or https://host:port
|
||||
# Note: database is not specified here since SQL files use ${DATABASE} prefix explicitly
|
||||
# For https:// endpoints, add secure=true&skip_verify=false for TLS as required by the goose ClickHouse driver
|
||||
case "$CLICKHOUSE_ENDPOINT" in
|
||||
https://*\?*) GOOSE_DBSTRING="${CLICKHOUSE_ENDPOINT}&username=${DB_USER}&password=${DB_PASSWORD}&secure=true&skip_verify=false" ;;
|
||||
https://*) GOOSE_DBSTRING="${CLICKHOUSE_ENDPOINT}?username=${DB_USER}&password=${DB_PASSWORD}&secure=true&skip_verify=false" ;;
|
||||
*\?*) GOOSE_DBSTRING="${CLICKHOUSE_ENDPOINT}&username=${DB_USER}&password=${DB_PASSWORD}" ;;
|
||||
*) GOOSE_DBSTRING="${CLICKHOUSE_ENDPOINT}?username=${DB_USER}&password=${DB_PASSWORD}" ;;
|
||||
esac
|
||||
|
||||
# Create temporary directory for processed SQL files
|
||||
TEMP_SCHEMA_DIR="/tmp/schema"
|
||||
mkdir -p "$TEMP_SCHEMA_DIR"
|
||||
|
||||
# Copy and process SQL files, replacing ${DATABASE} macro with actual database name
|
||||
echo "Preparing SQL files with database: $DB_NAME"
|
||||
cp -r /etc/otel/schema/* "$TEMP_SCHEMA_DIR/"
|
||||
find "$TEMP_SCHEMA_DIR" -name "*.sql" -exec sed -i "s/\${DATABASE}/${DB_NAME}/g" {} \;
|
||||
|
||||
# Track migration status
|
||||
MIGRATION_ERRORS=0
|
||||
|
||||
# Run migrations for each telemetry type
|
||||
for schema_dir in "$TEMP_SCHEMA_DIR"/*/; do
|
||||
if [ -d "$schema_dir" ]; then
|
||||
telemetry_type=$(basename "$schema_dir")
|
||||
echo "----------------------------------------"
|
||||
echo "Migrating $telemetry_type schemas..."
|
||||
echo "Directory: $schema_dir"
|
||||
|
||||
# List SQL files to be executed
|
||||
for sql_file in "$schema_dir"/*.sql; do
|
||||
if [ -f "$sql_file" ]; then
|
||||
echo " - $(basename "$sql_file")"
|
||||
fi
|
||||
done
|
||||
|
||||
# Run goose migration with exponential backoff retry for connection issues
|
||||
MAX_RETRIES=5
|
||||
RETRY_COUNT=0
|
||||
RETRY_DELAY=1
|
||||
MIGRATION_SUCCESS=false
|
||||
|
||||
# For _init schema, use 'default' database for version table since target DB doesn't exist yet
|
||||
if [ "$telemetry_type" = "_init" ]; then
|
||||
GOOSE_TABLE="default.clickstack_db_version_${telemetry_type}"
|
||||
else
|
||||
GOOSE_TABLE="${DB_NAME}.clickstack_db_version_${telemetry_type}"
|
||||
fi
|
||||
|
||||
while [ $RETRY_COUNT -lt $MAX_RETRIES ]; do
|
||||
if goose -table "$GOOSE_TABLE" -dir "$schema_dir" clickhouse "$GOOSE_DBSTRING" up; then
|
||||
echo "SUCCESS: $telemetry_type migrations completed"
|
||||
MIGRATION_SUCCESS=true
|
||||
break
|
||||
else
|
||||
RETRY_COUNT=$((RETRY_COUNT + 1))
|
||||
if [ $RETRY_COUNT -lt $MAX_RETRIES ]; then
|
||||
echo "RETRY: $telemetry_type migration failed, retrying in ${RETRY_DELAY}s... (attempt $RETRY_COUNT/$MAX_RETRIES)"
|
||||
sleep $RETRY_DELAY
|
||||
RETRY_DELAY=$((RETRY_DELAY * 2))
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$MIGRATION_SUCCESS" = false ]; then
|
||||
echo "ERROR: $telemetry_type migrations failed after $MAX_RETRIES attempts"
|
||||
MIGRATION_ERRORS=$((MIGRATION_ERRORS + 1))
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
# Cleanup temporary directory
|
||||
rm -rf "$TEMP_SCHEMA_DIR"
|
||||
|
||||
echo "========================================"
|
||||
if [ $MIGRATION_ERRORS -gt 0 ]; then
|
||||
echo "Schema migrations failed with $MIGRATION_ERRORS error(s)"
|
||||
echo "========================================"
|
||||
exit 1
|
||||
else
|
||||
echo "Schema migrations completed successfully"
|
||||
echo "========================================"
|
||||
fi
|
||||
# Run Go-based migrate tool with TLS support
|
||||
# TLS configuration:
|
||||
# - CLICKHOUSE_TLS_CA_FILE: CA certificate file
|
||||
# - CLICKHOUSE_TLS_CERT_FILE: Client certificate file
|
||||
# - CLICKHOUSE_TLS_KEY_FILE: Client private key file
|
||||
# - CLICKHOUSE_TLS_SERVER_NAME_OVERRIDE: Server name for TLS verification
|
||||
# - CLICKHOUSE_TLS_INSECURE_SKIP_VERIFY: Skip TLS verification (set to "true")
|
||||
echo "🚀 Using Go-based migrate tool with TLS support 🔐"
|
||||
migrate /etc/otel/schema/seed
|
||||
fi
|
||||
|
||||
# Check if OPAMP_SERVER_URL is defined to determine mode
|
||||
|
|
|
|||
376
packages/otel-collector/cmd/migrate/main.go
Normal file
376
packages/otel-collector/cmd/migrate/main.go
Normal file
|
|
@ -0,0 +1,376 @@
|
|||
// Package main provides a CLI tool for running ClickHouse schema seed using
|
||||
// goose without version tracking (WithNoVersioning). Seed SQL files are
|
||||
// re-applied on every run, so they MUST be idempotent (e.g. CREATE TABLE IF
|
||||
// NOT EXISTS). See docker/otel-collector/schema/seed/ for the SQL files.
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/ClickHouse/clickhouse-go/v2"
|
||||
"github.com/pressly/goose/v3"
|
||||
)
|
||||
|
||||
|
||||
// Config holds all configuration for the migration tool
|
||||
type Config struct {
|
||||
// ClickHouse connection settings
|
||||
Endpoint string
|
||||
User string
|
||||
Password string
|
||||
Database string
|
||||
|
||||
// TLS settings
|
||||
TLSCAFile string
|
||||
TLSCertFile string
|
||||
TLSKeyFile string
|
||||
TLSServerNameOverride string
|
||||
TLSInsecureSkipVerify bool
|
||||
|
||||
// Migration settings
|
||||
SchemaDir string
|
||||
MaxRetries int
|
||||
}
|
||||
|
||||
// loadConfig reads configuration from environment variables and CLI arguments
|
||||
func loadConfig() (*Config, error) {
|
||||
cfg := &Config{
|
||||
Endpoint: getEnv("CLICKHOUSE_ENDPOINT", "tcp://localhost:9000"),
|
||||
User: getEnv("CLICKHOUSE_USER", "default"),
|
||||
Password: getEnv("CLICKHOUSE_PASSWORD", ""),
|
||||
Database: getEnv("HYPERDX_OTEL_EXPORTER_CLICKHOUSE_DATABASE", "default"),
|
||||
TLSCAFile: getEnv("CLICKHOUSE_TLS_CA_FILE", ""),
|
||||
TLSCertFile: getEnv("CLICKHOUSE_TLS_CERT_FILE", ""),
|
||||
TLSKeyFile: getEnv("CLICKHOUSE_TLS_KEY_FILE", ""),
|
||||
TLSServerNameOverride: getEnv("CLICKHOUSE_TLS_SERVER_NAME_OVERRIDE", ""),
|
||||
TLSInsecureSkipVerify: getEnv("CLICKHOUSE_TLS_INSECURE_SKIP_VERIFY", "") == "true",
|
||||
MaxRetries: 5,
|
||||
}
|
||||
|
||||
// Get schema directory from CLI argument
|
||||
if len(os.Args) < 2 {
|
||||
return nil, fmt.Errorf("usage: %s <schema-directory>", os.Args[0])
|
||||
}
|
||||
cfg.SchemaDir = os.Args[1]
|
||||
|
||||
// Validate schema directory exists
|
||||
if _, err := os.Stat(cfg.SchemaDir); os.IsNotExist(err) {
|
||||
return nil, fmt.Errorf("schema directory does not exist: %s", cfg.SchemaDir)
|
||||
}
|
||||
|
||||
return cfg, nil
|
||||
}
|
||||
|
||||
// getEnv returns environment variable value or default if not set
|
||||
func getEnv(key, defaultValue string) string {
|
||||
if value := os.Getenv(key); value != "" {
|
||||
return value
|
||||
}
|
||||
return defaultValue
|
||||
}
|
||||
|
||||
// parseTLSConfig creates a TLS configuration from the provided settings
|
||||
func parseTLSConfig(cfg *Config) (*tls.Config, error) {
|
||||
tlsConfig := &tls.Config{
|
||||
InsecureSkipVerify: cfg.TLSInsecureSkipVerify,
|
||||
}
|
||||
|
||||
// Set server name override if provided
|
||||
if cfg.TLSServerNameOverride != "" {
|
||||
tlsConfig.ServerName = cfg.TLSServerNameOverride
|
||||
}
|
||||
|
||||
// Load CA certificate if provided
|
||||
if cfg.TLSCAFile != "" {
|
||||
caCert, err := os.ReadFile(cfg.TLSCAFile)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read CA certificate file: %w", err)
|
||||
}
|
||||
caCertPool := x509.NewCertPool()
|
||||
if !caCertPool.AppendCertsFromPEM(caCert) {
|
||||
return nil, fmt.Errorf("failed to parse CA certificate")
|
||||
}
|
||||
tlsConfig.RootCAs = caCertPool
|
||||
}
|
||||
|
||||
// Load client certificate and key if both are provided
|
||||
if cfg.TLSCertFile != "" && cfg.TLSKeyFile != "" {
|
||||
cert, err := tls.LoadX509KeyPair(cfg.TLSCertFile, cfg.TLSKeyFile)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to load client certificate: %w", err)
|
||||
}
|
||||
tlsConfig.Certificates = []tls.Certificate{cert}
|
||||
}
|
||||
|
||||
return tlsConfig, nil
|
||||
}
|
||||
|
||||
// parseEndpoint parses the CLICKHOUSE_ENDPOINT and returns connection options
|
||||
func parseEndpoint(endpoint string) (protocol string, host string, port string, secure bool, err error) {
|
||||
// Default values
|
||||
protocol = "native"
|
||||
port = "9000"
|
||||
secure = false
|
||||
|
||||
// Parse the URL
|
||||
if !strings.Contains(endpoint, "://") {
|
||||
endpoint = "tcp://" + endpoint
|
||||
}
|
||||
|
||||
u, err := url.Parse(endpoint)
|
||||
if err != nil {
|
||||
return "", "", "", false, fmt.Errorf("failed to parse endpoint: %w", err)
|
||||
}
|
||||
|
||||
host = u.Hostname()
|
||||
if u.Port() != "" {
|
||||
port = u.Port()
|
||||
}
|
||||
|
||||
switch u.Scheme {
|
||||
case "tcp":
|
||||
protocol = "native"
|
||||
port = getOrDefault(u.Port(), "9000")
|
||||
case "http":
|
||||
protocol = "http"
|
||||
port = getOrDefault(u.Port(), "8123")
|
||||
case "https":
|
||||
protocol = "http"
|
||||
port = getOrDefault(u.Port(), "8443")
|
||||
secure = true
|
||||
default:
|
||||
return "", "", "", false, fmt.Errorf("unsupported protocol: %s", u.Scheme)
|
||||
}
|
||||
|
||||
return protocol, host, port, secure, nil
|
||||
}
|
||||
|
||||
func getOrDefault(value, defaultValue string) string {
|
||||
if value == "" {
|
||||
return defaultValue
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
// createClickHouseDB creates a database connection to ClickHouse
|
||||
func createClickHouseDB(cfg *Config) (*sql.DB, error) {
|
||||
protocol, host, port, secure, err := parseEndpoint(cfg.Endpoint)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Build connection options
|
||||
// Note: Connection pool settings (MaxOpenConns, MaxIdleConns, ConnMaxLifetime)
|
||||
// must be set on the *sql.DB object, not in clickhouse.Options when using OpenDB()
|
||||
opts := &clickhouse.Options{
|
||||
Addr: []string{fmt.Sprintf("%s:%s", host, port)},
|
||||
Auth: clickhouse.Auth{
|
||||
Username: cfg.User,
|
||||
Password: cfg.Password,
|
||||
},
|
||||
Protocol: clickhouse.Native,
|
||||
Settings: clickhouse.Settings{
|
||||
"max_execution_time": 60,
|
||||
},
|
||||
Compression: &clickhouse.Compression{
|
||||
Method: clickhouse.CompressionLZ4,
|
||||
},
|
||||
DialTimeout: 30 * time.Second,
|
||||
ConnOpenStrategy: clickhouse.ConnOpenInOrder,
|
||||
}
|
||||
|
||||
// Set protocol
|
||||
if protocol == "http" {
|
||||
opts.Protocol = clickhouse.HTTP
|
||||
}
|
||||
|
||||
// Configure TLS if needed
|
||||
if secure || cfg.TLSCAFile != "" || cfg.TLSCertFile != "" {
|
||||
tlsConfig, err := parseTLSConfig(cfg)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create TLS config: %w", err)
|
||||
}
|
||||
opts.TLS = tlsConfig
|
||||
}
|
||||
|
||||
// Open connection using database/sql interface (required for goose)
|
||||
db := clickhouse.OpenDB(opts)
|
||||
|
||||
// Set connection pool settings on the *sql.DB object
|
||||
db.SetMaxOpenConns(5)
|
||||
db.SetMaxIdleConns(5)
|
||||
db.SetConnMaxLifetime(10 * time.Minute)
|
||||
|
||||
return db, nil
|
||||
}
|
||||
|
||||
// processSchemaDir creates a temporary directory with SQL files that have
|
||||
// the ${DATABASE} macro replaced with the actual database name
|
||||
func processSchemaDir(schemaDir, database string) (string, error) {
|
||||
tempDir, err := os.MkdirTemp("", "schema-*")
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to create temp directory: %w", err)
|
||||
}
|
||||
|
||||
// Walk through the schema directory and process SQL files
|
||||
err = filepath.Walk(schemaDir, func(path string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Get relative path from schema directory
|
||||
relPath, err := filepath.Rel(schemaDir, path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
destPath := filepath.Join(tempDir, relPath)
|
||||
|
||||
if info.IsDir() {
|
||||
return os.MkdirAll(destPath, 0755)
|
||||
}
|
||||
|
||||
// Read the file
|
||||
content, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to read file %s: %w", path, err)
|
||||
}
|
||||
|
||||
// Replace ${DATABASE} macro with actual database name
|
||||
processedContent := strings.ReplaceAll(string(content), "${DATABASE}", database)
|
||||
|
||||
// Write processed content to temp directory
|
||||
if err := os.WriteFile(destPath, []byte(processedContent), 0644); err != nil {
|
||||
return fmt.Errorf("failed to write file %s: %w", destPath, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
os.RemoveAll(tempDir)
|
||||
return "", fmt.Errorf("failed to process schema directory: %w", err)
|
||||
}
|
||||
|
||||
return tempDir, nil
|
||||
}
|
||||
|
||||
|
||||
// runMigrationWithRetry runs goose seed with exponential backoff retry
|
||||
func runMigrationWithRetry(ctx context.Context, db *sql.DB, migrationsDir string, maxRetries int) error {
|
||||
var lastErr error
|
||||
retryDelay := time.Second
|
||||
|
||||
for attempt := 1; attempt <= maxRetries; attempt++ {
|
||||
// Set dialect to clickhouse
|
||||
if err := goose.SetDialect("clickhouse"); err != nil {
|
||||
return fmt.Errorf("failed to set goose dialect: %w", err)
|
||||
}
|
||||
|
||||
// Run the migrations with no versioning to avoid ClickHouse transaction
|
||||
// issues with goose's version table. All migration SQL files must be
|
||||
// idempotent (e.g. CREATE TABLE IF NOT EXISTS).
|
||||
if err := goose.UpContext(ctx, db, migrationsDir, goose.WithNoVersioning()); err != nil {
|
||||
lastErr = err
|
||||
if attempt < maxRetries {
|
||||
log.Printf("RETRY: Seed failed, retrying in %v... (attempt %d/%d): %v",
|
||||
retryDelay, attempt, maxRetries, err)
|
||||
time.Sleep(retryDelay)
|
||||
retryDelay *= 2 // Exponential backoff
|
||||
continue
|
||||
}
|
||||
} else {
|
||||
return nil // Success
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Errorf("seed failed after %d attempts: %w", maxRetries, lastErr)
|
||||
}
|
||||
|
||||
// listSQLFiles lists all SQL files in a directory for logging purposes
|
||||
func listSQLFiles(dir string) ([]string, error) {
|
||||
entries, err := os.ReadDir(dir)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var files []string
|
||||
for _, entry := range entries {
|
||||
if !entry.IsDir() && strings.HasSuffix(entry.Name(), ".sql") {
|
||||
files = append(files, entry.Name())
|
||||
}
|
||||
}
|
||||
sort.Strings(files)
|
||||
return files, nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
log.SetFlags(log.Ltime | log.Lmsgprefix)
|
||||
log.SetPrefix("[seed] ")
|
||||
|
||||
// Load configuration
|
||||
cfg, err := loadConfig()
|
||||
if err != nil {
|
||||
log.Fatalf("Configuration error: %v", err)
|
||||
}
|
||||
|
||||
log.Println("========================================")
|
||||
log.Println("Running ClickHouse schema seed...")
|
||||
log.Println("========================================")
|
||||
log.Printf("Target database: %s", cfg.Database)
|
||||
log.Printf("Schema directory: %s", cfg.SchemaDir)
|
||||
|
||||
// Create database connection
|
||||
db, err := createClickHouseDB(cfg)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to create database connection: %v", err)
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
// Test connection
|
||||
ctx := context.Background()
|
||||
if err := db.PingContext(ctx); err != nil {
|
||||
log.Fatalf("Failed to connect to ClickHouse: %v", err)
|
||||
}
|
||||
log.Println("Successfully connected to ClickHouse")
|
||||
|
||||
// Process schema directory (replace ${DATABASE} macro)
|
||||
log.Printf("Preparing SQL files with database: %s", cfg.Database)
|
||||
tempDir, err := processSchemaDir(cfg.SchemaDir, cfg.Database)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to process schema directory: %v", err)
|
||||
}
|
||||
defer os.RemoveAll(tempDir)
|
||||
|
||||
// List SQL files
|
||||
sqlFiles, err := listSQLFiles(tempDir)
|
||||
if err != nil {
|
||||
log.Printf("WARNING: Failed to list SQL files: %v", err)
|
||||
} else {
|
||||
for _, f := range sqlFiles {
|
||||
log.Printf(" - %s", f)
|
||||
}
|
||||
}
|
||||
|
||||
// Run seed with retry
|
||||
if err := runMigrationWithRetry(ctx, db, tempDir, cfg.MaxRetries); err != nil {
|
||||
log.Printf("ERROR: Schema seed failed after %d attempts: %v", cfg.MaxRetries, err)
|
||||
log.Println("========================================")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
log.Println("========================================")
|
||||
log.Println("Schema seed completed successfully")
|
||||
log.Println("========================================")
|
||||
}
|
||||
30
packages/otel-collector/go.mod
Normal file
30
packages/otel-collector/go.mod
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
module github.com/hyperdxio/hyperdx/packages/otel-collector
|
||||
|
||||
go 1.25
|
||||
|
||||
require (
|
||||
github.com/ClickHouse/clickhouse-go/v2 v2.30.0
|
||||
github.com/pressly/goose/v3 v3.24.1
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/ClickHouse/ch-go v0.61.5 // indirect
|
||||
github.com/andybalholm/brotli v1.1.1 // indirect
|
||||
github.com/go-faster/city v1.0.1 // indirect
|
||||
github.com/go-faster/errors v0.7.1 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/klauspost/compress v1.17.7 // indirect
|
||||
github.com/mfridman/interpolate v0.0.2 // indirect
|
||||
github.com/paulmach/orb v0.11.1 // indirect
|
||||
github.com/pierrec/lz4/v4 v4.1.21 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/segmentio/asm v1.2.0 // indirect
|
||||
github.com/sethvargo/go-retry v0.3.0 // indirect
|
||||
github.com/shopspring/decimal v1.4.0 // indirect
|
||||
go.opentelemetry.io/otel v1.26.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.26.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
golang.org/x/sync v0.10.0 // indirect
|
||||
golang.org/x/sys v0.28.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
146
packages/otel-collector/go.sum
Normal file
146
packages/otel-collector/go.sum
Normal file
|
|
@ -0,0 +1,146 @@
|
|||
github.com/ClickHouse/ch-go v0.61.5 h1:zwR8QbYI0tsMiEcze/uIMK+Tz1D3XZXLdNrlaOpeEI4=
|
||||
github.com/ClickHouse/ch-go v0.61.5/go.mod h1:s1LJW/F/LcFs5HJnuogFMta50kKDO0lf9zzfrbl0RQg=
|
||||
github.com/ClickHouse/clickhouse-go/v2 v2.30.0 h1:AG4D/hW39qa58+JHQIFOSnxyL46H6h2lrmGGk17dhFo=
|
||||
github.com/ClickHouse/clickhouse-go/v2 v2.30.0/go.mod h1:i9ZQAojcayW3RsdCb3YR+n+wC2h65eJsZCscZ1Z1wyo=
|
||||
github.com/andybalholm/brotli v1.1.1 h1:PR2pgnyFznKEugtsUo0xLdDop5SKXd5Qf5ysW+7XdTA=
|
||||
github.com/andybalholm/brotli v1.1.1/go.mod h1:05ib4cKhjx3OQYUY22hTVd34Bc8upXjOLL2rKwwZBoA=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
|
||||
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
|
||||
github.com/go-faster/city v1.0.1 h1:4WAxSZ3V2Ws4QRDrscLEDcibJY8uf41H6AhXDrNDcGw=
|
||||
github.com/go-faster/city v1.0.1/go.mod h1:jKcUJId49qdW3L1qKHH/3wPeUstCVpVSXTM6vO3VcTw=
|
||||
github.com/go-faster/errors v0.7.1 h1:MkJTnDoEdi9pDabt1dpWf7AA8/BaSYZqibYyhZ20AYg=
|
||||
github.com/go-faster/errors v0.7.1/go.mod h1:5ySTjWFiphBs07IKuiL69nxdfd5+fzh1u7FPGZP2quo=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
|
||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
||||
github.com/klauspost/compress v1.17.7 h1:ehO88t2UGzQK66LMdE8tibEd1ErmzZjNEqWkjLAKQQg=
|
||||
github.com/klauspost/compress v1.17.7/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mfridman/interpolate v0.0.2 h1:pnuTK7MQIxxFz1Gr+rjSIx9u7qVjf5VOoM/u6BbAxPY=
|
||||
github.com/mfridman/interpolate v0.0.2/go.mod h1:p+7uk6oE07mpE/Ik1b8EckO0O4ZXiGAfshKBWLUM9Xg=
|
||||
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
|
||||
github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4=
|
||||
github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=
|
||||
github.com/paulmach/orb v0.11.1 h1:3koVegMC4X/WeiXYz9iswopaTwMem53NzTJuTF20JzU=
|
||||
github.com/paulmach/orb v0.11.1/go.mod h1:5mULz1xQfs3bmQm63QEJA6lNGujuRafwA5S/EnuLaLU=
|
||||
github.com/paulmach/protoscan v0.2.1/go.mod h1:SpcSwydNLrxUGSDvXvO0P7g7AuhJ7lcKfDlhJCDw2gY=
|
||||
github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ=
|
||||
github.com/pierrec/lz4/v4 v4.1.21/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/pressly/goose/v3 v3.24.1 h1:bZmxRco2uy5uu5Ng1MMVEfYsFlrMJI+e/VMXHQ3C4LY=
|
||||
github.com/pressly/goose/v3 v3.24.1/go.mod h1:rEWreU9uVtt0DHCyLzF9gRcWiiTF/V+528DV+4DORug=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
|
||||
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
|
||||
github.com/segmentio/asm v1.2.0 h1:9BQrFxC+YOHJlTlHGkTrFWf59nbL3XnCoFLTwDCI7ys=
|
||||
github.com/segmentio/asm v1.2.0/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs=
|
||||
github.com/sethvargo/go-retry v0.3.0 h1:EEt31A35QhrcRZtrYFDTBg91cqZVnFL2navjDrah2SE=
|
||||
github.com/sethvargo/go-retry v0.3.0/go.mod h1:mNX17F0C/HguQMyMyJxcnU471gOZGxCLyYaFyAZraas=
|
||||
github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k=
|
||||
github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
||||
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
|
||||
github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g=
|
||||
github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8=
|
||||
github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU=
|
||||
github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E=
|
||||
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
go.mongodb.org/mongo-driver v1.11.4/go.mod h1:PTSz5yu21bkT/wXpkS7WR5f0ddqw5quethTUn9WM+2g=
|
||||
go.opentelemetry.io/otel v1.26.0 h1:LQwgL5s/1W7YiiRwxf03QGnWLb2HW4pLiAhaA5cZXBs=
|
||||
go.opentelemetry.io/otel v1.26.0/go.mod h1:UmLkJHUAidDval2EICqBMbnAd0/m2vmpf/dAM+fvFs4=
|
||||
go.opentelemetry.io/otel/trace v1.26.0 h1:1ieeAUb4y0TE26jUFrCIXKpTuVK7uJGN9/Z/2LP5sQA=
|
||||
go.opentelemetry.io/otel/trace v1.26.0/go.mod h1:4iDxvGDQuUkHve82hJJ8UqrwswHYsZuWCBllGV2U2y0=
|
||||
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
||||
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
|
||||
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
|
||||
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 h1:5D53IMaUuA5InSeMu9eJtlQXS2NxAhyWQvkKEgXZhHI=
|
||||
modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6/go.mod h1:Qz0X07sNOR1jWYCrJMEnbW/X55x206Q7Vt4mz6/wHp4=
|
||||
modernc.org/libc v1.55.3 h1:AzcW1mhlPNrRtjS5sS+eW2ISCgSOLLNyFzRh/V3Qj/U=
|
||||
modernc.org/libc v1.55.3/go.mod h1:qFXepLhz+JjFThQ4kzwzOjA/y/artDeg+pcYnY+Q83w=
|
||||
modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4=
|
||||
modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo=
|
||||
modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E=
|
||||
modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU=
|
||||
modernc.org/sqlite v1.34.1 h1:u3Yi6M0N8t9yKRDwhXcyp1eS5/ErhPTBggxWFuR6Hfk=
|
||||
modernc.org/sqlite v1.34.1/go.mod h1:pXV2xHxhzXZsgT/RtTFAPY6JJDEvOTcTdwADQCCWD4k=
|
||||
modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA=
|
||||
modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0=
|
||||
modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y=
|
||||
modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
|
||||
|
|
@ -20,7 +20,8 @@ services:
|
|||
start_period: 10s
|
||||
otel-collector:
|
||||
build:
|
||||
context: ../../docker/otel-collector
|
||||
context: ../..
|
||||
dockerfile: docker/otel-collector/Dockerfile
|
||||
target: dev
|
||||
environment:
|
||||
- CLICKHOUSE_ENDPOINT=tcp://ch-server:9000?dial_timeout=10s
|
||||
|
|
|
|||
Loading…
Reference in a new issue