hyperdx icon indicating copy to clipboard operation
hyperdx copied to clipboard

ServiceName column empty value on otel_logs table

Open espin2 opened this issue 5 months ago • 4 comments

currently i'm facing issue can't get value from ServiceName column (empty string or null) for otel_logs table, but for trace & metrics table, the value is appear.i use this config for otel agent. is there any configuration i have to setup?or i miss something?

for temporary solution i create new column with materialized column to get service name from ResourceAttributes.

`AppName` LowCardinality(String) MATERIALIZED
    coalesce(
        nullIf(ResourceAttributes['k8s.deployment.name'], ''),
        nullIf(ResourceAttributes['k8s.statefulset.name'], ''),
        nullIf(ResourceAttributes['k8s.daemonset.name'], ''),
        nullIf(ResourceAttributes['k8s.cronjob.name'], ''),
        nullIf(ResourceAttributes['k8s.job.name'], ''),
        nullIf(ResourceAttributes['app.kubernetes.io/name'], ''),
        'unknown'  
    )
    CODEC(ZSTD(1)),

empty value ServiceName column Image

has value AppName column with MATERIALIZED Column

Image

espin2 avatar Aug 18 '25 22:08 espin2

Hi. What version of HyperDX are you using?

Assuming it's 2.x, how is ServiceName mapped in the otel_logs source? Is that column being populated from the client-side?

teeohhem avatar Aug 20 '25 19:08 teeohhem

Hi @teeohhem , i'm using HyperDX 2.12. this is the custom sql tables otel_logs. just add AppName column and modify storage_policy. the rest is by default.

    CREATE TABLE IF NOT EXISTS default.otel_logs 
    (
        `Timestamp` DateTime64(9) CODEC(Delta(8), ZSTD(1)),
        `TimestampTime` DateTime DEFAULT toDateTime(Timestamp),
        `TraceId` String CODEC(ZSTD(1)),
        `SpanId` String CODEC(ZSTD(1)),
        `TraceFlags` UInt8,
        `SeverityText` LowCardinality(String) CODEC(ZSTD(1)),
        `SeverityNumber` UInt8,
        `ServiceName` LowCardinality(String) CODEC(ZSTD(1)),
        `AppName` LowCardinality(String) MATERIALIZED
            coalesce(
                nullIf(ResourceAttributes['k8s.deployment.name'], ''),
                nullIf(ResourceAttributes['k8s.statefulset.name'], ''),
                nullIf(ResourceAttributes['k8s.daemonset.name'], ''),
                nullIf(ResourceAttributes['k8s.cronjob.name'], ''),
                nullIf(ResourceAttributes['k8s.job.name'], ''),
                nullIf(ResourceAttributes['app.kubernetes.io/name'], ''),
                'unknown'  
            )
            CODEC(ZSTD(1)),
        `Body` String CODEC(ZSTD(1)),
        `ResourceSchemaUrl` LowCardinality(String) CODEC(ZSTD(1)),
        `ResourceAttributes` Map(LowCardinality(String), String) CODEC(ZSTD(1)),
        `ScopeSchemaUrl` LowCardinality(String) CODEC(ZSTD(1)),
        `ScopeName` String CODEC(ZSTD(1)),
        `ScopeVersion` LowCardinality(String) CODEC(ZSTD(1)),
        `ScopeAttributes` Map(LowCardinality(String), String) CODEC(ZSTD(1)),
        `LogAttributes` Map(LowCardinality(String), String) CODEC(ZSTD(1)),
        INDEX idx_trace_id TraceId TYPE bloom_filter(0.001) GRANULARITY 1,
        INDEX idx_res_attr_key mapKeys(ResourceAttributes) TYPE bloom_filter(0.01) GRANULARITY 1,
        INDEX idx_res_attr_value mapValues(ResourceAttributes) TYPE bloom_filter(0.01) GRANULARITY 1,
        INDEX idx_scope_attr_key mapKeys(ScopeAttributes) TYPE bloom_filter(0.01) GRANULARITY 1,
        INDEX idx_scope_attr_value mapValues(ScopeAttributes) TYPE bloom_filter(0.01) GRANULARITY 1,
        INDEX idx_log_attr_key mapKeys(LogAttributes) TYPE bloom_filter(0.01) GRANULARITY 1,
        INDEX idx_log_attr_value mapValues(LogAttributes) TYPE bloom_filter(0.01) GRANULARITY 1,
        INDEX idx_body Body TYPE tokenbf_v1(32768, 3, 0) GRANULARITY 8,
    )
    ENGINE = MergeTree() 
    PARTITION BY toDate(TimestampTime)
    PRIMARY KEY (AppName, TimestampTime)
    ORDER BY (AppName, TimestampTime, Timestamp)
    TTL TimestampTime + toIntervalDay(1) TO VOLUME 'cold'
    SETTINGS storage_policy = 'tiered_logs', index_granularity = 8192, ttl_only_drop_parts = 1;

espin2 avatar Aug 20 '25 22:08 espin2

@espin2 you'll need to add service name yourself in this case (as there's not really a default value we assign this case).

Ex. you can extend the OTEL_RESOURCE_ATTRIBUTES to include service.name that takes in POD_NAME in the forwarding resource tags section of the docs.

MikeShi42 avatar Aug 21 '25 06:08 MikeShi42

got it, it's effort to me to add new label service.name on every deployment, so i'm deciding to relabel from otel agent side like below config. this is my custom config, you can change anything according your needs.

    processors:
      resource/deploy_to_service:
        attributes:
          - key: service.name
            from_attribute: k8s.deployment.name
            action: insert

      resource/sts_to_service:
        attributes:
          - key: service.name
            from_attribute: k8s.statefulset.name
            action: insert

      resource/ds_to_service:
        attributes:
          - key: service.name
            from_attribute: k8s.daemonset.name
            action: insert

      resource/job_to_service:
        attributes:
          - key: service.name
            from_attribute: k8s.job.name
            action: insert

      resource/cronjob_to_service:
        attributes:
          - key: service.name
            from_attribute: k8s.cronjob.name
            action: insert

espin2 avatar Aug 22 '25 14:08 espin2