Skip to content

Dataway


Introduction

DataWay is the data gateway of the Guance, and the collector needs to pass through the DataWay gateway to report data to the Guance.

Dataway Installation

  • New Dataway

On the Data Gateways page in the Guance management console, click Create Dataway. Enter a name and binding address, and then click Create.

After the creation is successful, a new Dataway is automatically created and the installation script for the Dataway is generated.

Info

The binding address is the Dataway gateway address, which must be filled in as a complete HTTP address, such as http(s)://1.2.3.4:9528, including the protocol, host address and port, the host address can generally use the IP address of the Dataway machine deployed or specified as a domain name, and the domain name needs to be resolved.

Note: Make sure that the collector can access the address, otherwise the data collection will not be successful)

  • Install Dataway
DW_KODO=http://kodo_ip:port \
   DW_TOKEN=<tkn_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX> \
   DW_UUID=<YOUR_UUID> \
   bash -c "$(curl https://static.guance.com/dataway/install.sh)"

Install Dataway on host is deprecated, we should install Dataway in Kubernetes as statefulset.

After the installation is complete, in the installation directory, dataway.yaml will be generated, the content of which can be manually modified and take effect by restarting the service.

dataway.yaml
# ============= DATAWAY CONFIG =============

# Dataway UUID, we can get it on during create a new dataway
uuid:

# It's the workspace token, most of the time, it's
# system worker space's token.
token:

# secret_token used under sinker mode, and to check if incomming datakit
# requests are valid.
secret_token:

# If __internal__ token allowed? If ok, the data/request will direct to
# the workspace with the token above
enable_internal_token: false

# is empty token allowed? If ok, the data/request will direct to
# the workspace with the token above
enable_empty_token: false

# Is dataway cascaded? For cascaded Dataway, it's remote_host is
# another Dataway and not Kodo.
cascaded: false

# kodo(next dataway) related configures
remote_host:
http_timeout: 3s
# Inbound HTTP deadlines, independent of downstream request timeout
http_read_timeout: 5m
http_write_timeout: 10m
http_idle_timeout: 2m

http_max_idle_conn_perhost: 0 # default to CPU cores
http_max_conn_perhost: 0      # default no limit
kodo_queue:
  enabled: true
  # Also limits concurrent HTTP requests before body reading.
  workers: 256
  queue_size: 1024
  queue_max_bytes: 1073741824 # 1GB
  enqueue_timeout: 100ms

insecure_skip_verify: false
http_client_trace: false
sni: ""

# dataway API configures
# IPv4 and IPv6 use independent listeners to avoid OS bindv6only differences.
bind: 0.0.0.0:9528
# IPv6 is disabled by default. Set this to "[::]:9528" to enable it.
bind_ipv6: ""

# Forwarded IP headers are trusted for whitelist checks only from these proxies.
# trusted_proxies:
#   - 10.0.0.0/8
#   - 2001:db8:ffff::/48

# disable 404 page
disable_404page: false

# dataway TLS file path
tls_crt:
tls_key:

# pprof is disabled by default and accepts loopback listeners only
pprof_bind: ""

api_limit_rate : 100000         # 100K
max_http_body_bytes : 67108864  # 64MB
copy_buffer_drop_size : 262144  # 256KB, if copy buffer memory larger than this, this memory released
reserved_pool_size: 4096        # reserved pool size for better GC

within_docker: false

log_level: info
log: log
gin_log: gin.log

ip_black_list:
  ttl: "1m"
  clean_interval: "1h"

cache_cfg:
  # cache disk path
  dir: "disk_cache"

  # disable cache
  disabled: false

  clean_interval: "1s"

  # in MB, max single data package size in disk cache, such as HTTP body
  max_data_size: 100

  # in MB, single disk-batch(single file) size
  batch_size: 128

  # in MB, max disk size allowed to cache data
  max_disk_size: 65535

  # expire duration, default 7 days
  expire_duration: "168h"

prometheus:
  listen: "localhost:9090"
  url: "/metrics"
  enable: true

#sinker:
#  cache_options:
#    prealloc: true
#    reserved_capacity: 10000000 # max cached items
#    buckets: 64
#    ttl: 10m # clear unactive matches
#  etcd:
#    urls:
#    - http://localhost:2379 # one or multiple etcd host
#    dial_timeout: 30s
#    key_space: "/dw_sinker" # subscribe to the etcd key
#    username: "dataway"
#    password: "<PASSWORD>"
#  file:
#    path: /path/to/sinker.json

Dataway pod yaml:

dataway-statefulset.yaml
---

apiVersion: apps/v1
kind: StatefulSet
metadata:
  labels:
    app: sts-utils-dataway
  name: dataway
  namespace: utils
spec:
  replicas: 2
  selector:
    matchLabels:
      app: sts-utils-dataway
  serviceName: dataway
  template:
    metadata:
      annotations:
        datakit/logs: |
          [
            {
              "disable": false,
              "source": "dataway",
              "service": "dataway",
              "multiline_match": "^\\d{4}|^\\[GIN\\]"
            }
          ]
        datakit/prom.instances: |
          [[inputs.prom]]
            url = "http://$IP:9090/metrics"

            source = "dataway"
            measurement_name = "dw"
            interval = "10s"
            disable_instance_tag = true
          [inputs.prom.tags]
            service = "dataway"
            instance = "$PODNAME" # we can set as "xxx-$PODNAME"
      labels:
        app: sts-utils-dataway
    spec:
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            - labelSelector:
                matchExpressions:
                  - key: app
                    operator: In
                    values:
                      - sts-utils-dataway
              topologyKey: kubernetes.io/hostname
      containers:
        - env:
            - name: DW_REMOTE_HOST
              value: http://kodo.forethought-kodo:9527
            - name: DW_BIND
              value: 0.0.0.0:9528
            # Uncomment the next two lines to listen on IPv6.
            # - name: DW_BIND_IPV6
            #   value: "[::]:9528"
            - name: DW_UUID
              value: agnt_xxxxxxxxxxxxxxxxxxxxxxxxxxxxx   # Dataway UUID
            - name: DW_TOKEN
              value: tkn_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx  # Dataway token
            - name: DW_PROM_LISTEN
              value: 0.0.0.0:9090
            - name: DW_LOG
              value: stdout
            - name: DW_LOG_LEVEL
              value: info
            - name: DW_GIN_LOG
              value: stdout
            - name: DW_DISKCACHE_DIR
              value: cache
            - name: DW_HTTP_TIMEOUT
              value: '3s'
            - name: DW_ENABLE_INTERNAL_TOKEN
              value: 'false'
            - name: DW_MAX_HTTP_BODY_BYTES
              value: '67108864'
            - name: DW_HTTP_CLIENT_TRACE
              value: 'on'
            - name: DW_RESERVED_POOL_SIZE
              value: '0'
            - name: DW_COPY_BUFFER_DROP_SIZE
              value: '262144'
            - name: DW_DISKCACHE_CAPACITY_MB
              value: 102400
          image: pubrepo.guance.com/dataflux/dataway:1.21.0
          imagePullPolicy: IfNotPresent
          name: dataway
          ports:
            - containerPort: 9528
              name: 9528tcp01
              protocol: TCP
          resources:
            limits:
              cpu: '4'
              memory: 4Gi
            requests:
              cpu: 100m
              memory: 512Mi
          terminationMessagePath: /dev/termination-log
          terminationMessagePolicy: File
          volumeMounts:
            - mountPath: /usr/local/cloudcare/dataflux/dataway/cache
              name: dataway-cache
      dnsPolicy: ClusterFirst
      imagePullSecrets: []
      #nodeSelector:
      #  nodepool: dataway
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30
      #tolerations:
      #  - effect: NoSchedule
      #    key: nodepool
      #    operator: Equal
      #    value: dataway
  updateStrategy:
    rollingUpdate:
      partition: 0
    type: RollingUpdate
  volumeClaimTemplates:
    - apiVersion: v1
      kind: PersistentVolumeClaim
      metadata:
        name: dataway-cache
      spec:
        accessModes:
          - ReadWriteOnce
        resources:
          requests:
            storage: 100Gi
        storageClassName: xxxxxx  # High-Performance Storage StorageClass
        volumeMode: Filesystem
      status:
        phase: Pending

---

apiVersion: v1
kind: Service
metadata:
  name: dataway
  namespace: utils
spec:
  ipFamilyPolicy: SingleStack # Use PreferDualStack for dual-stack mode
  # ipFamilies:
  #   - IPv4
  #   - IPv6
  ports:
    - name: 9528tcp02
      nodePort: 30928
      port: 9528
      protocol: TCP
      targetPort: 9528
  selector:
    app: sts-utils-dataway
  type: NodePort
---

apiVersion: v1
kind: Service
metadata:
  name: dataway
  namespace: utils
spec:
  ipFamilyPolicy: SingleStack # Use PreferDualStack for dual-stack mode
  # ipFamilies:
  #   - IPv4
  #   - IPv6
  ports:
  - name: 9528tcp02
    port: 9528
    protocol: TCP
    targetPort: 9528
    nodePort: 30928
  selector:
    app: deployment-utils-dataway
  type: NodePort

The default example uses IPv4 single-stack. To enable dual-stack, first verify that the Kubernetes cluster and CNI support IPv4/IPv6 dual-stack, then make both of these changes:

  1. Uncomment DW_BIND_IPV6 in the Dataway container environment and set it to [::]:9528 so that Dataway listens on both IPv4 and IPv6.
  2. Change the Service ipFamilyPolicy from SingleStack to PreferDualStack, then uncomment the IPv4 and IPv6 entries under ipFamilies.

Both changes are required. If only the Service is changed without setting DW_BIND_IPV6, Dataway will not accept IPv6 requests.

In dataway-statefulset.yaml, you can modify the Dataway configuration through environment variables, see [here] (dataway.md#img-envs).

For DataWay docker install, the environments are the same as in Kubernetes. We can start a DataWay docker container like this:

docker run -d \
    --name <YOUR-DW-IN-DOCKER> \
    -p 19528:9528 -p 19090:9090 \
    --mount type=bind,source=<host/path/for/diskcache>,target=/usr/local/cloudcare/dataflux/dataway/cache \
    --memory=2g --memory-reservation=256m \
    --cpus="2" \
    -e DW_UUID=<YOUR-AGNT_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX> \
    -e DW_TOKEN=<YOUR-TKN_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX> \
    -e DW_REMOTE_HOST=http://kodo.forethought-kodo:9527 \
    -e DW_BIND=0.0.0.0:9528 \
    -e DW_PROM_LISTEN=0.0.0.0:9090 \
    -e DW_HTTP_CLIENT_TRACE=true \
    -e DW_LOG_LEVEL=info \
    -e DW_LOG=stdout \
    -e DW_GIN_LOG=stdout \
    -e DW_DISKCACHE_CAPACITY_MB=65536 \
    pubrepo.guance.com/dataflux/dataway:1.21.0

Notes
  • Can only run on Linux systems
  • When the host is installed, the Dataway installation path is /usr/local/cloudcare/dataflux/dataway
  • Verify Dataway installation

After installation, wait for a while to refresh the "Data Gateway" page, if you see the version number in the "Version Information" column of the data gateway you just added, it means that the Dataway has been successfully connected to the Guance center, and front-end users can access data through it.

After Dataway is successfully connected to the Guance center, log in to the Guance console, view all Dataway addresses on the "Integration" / DataKit page, select the required Dataway gateway address, and obtain the DataKit installation command to execute on the server to start collecting data.

Manage DataWay

Delete DataWay

On the "Data Gateway" page of the Guance management background, select the DataWay to be deleted, click "Configure", and click the "Delete" button in the lower left corner of the pop-up Edit DataWay dialog box.

Warning

After deleting DataWay, you also need to log in to the server where the DataWay gateway is deployed to stop the operation of DataWay, and then delete the installation directory to completely delete the DataWay.

Upgrade DataWay

On the Data Gateways page in the Guance management background, if an upgradeable version exists for DataWay, an upgrade prompt appears in the version information.

DW_UPGRADE=1 bash -c "$(curl https://static.guance.com/dataway/install.sh)"

Replace the image version directly:

- image: pubrepo.guance.com/dataflux/dataway:1.21.0

Dataway Service Management

When the host installs Dataway, you can use the following command to manage the Dataway service:

# Start
$ systemctl start dataway

# Reboot
$ systemctl restart dataway

# Stop
$ systemctl stop dataway

Kubernetes can restart the corresponding pod.

Environment variable

Docker image environment variable

When Dataway runs in a Kubernetes environment, it supports the following environment variables.

Compatible with lagacy dataway.yaml

Some old Dataway's configure imported by ConfigMap(and mount to install path with the name of dataway.yaml). After Dataway image started, if detect the file dataway.yaml, all the configures from DW_* are ignored and only apply the lagacy dataway.yaml. We can remove the ConfigMap on dataway.yaml to recover these environment configures.

If these environment configures applied, there was a hidden file .dataway.ayml(view them via ls -a) under install path, we can cat it to check if all these environment configures applied ok.

HTTP Server Settings

HTTP concurrency is limited before request bodies are read, using kodo_queue.workers (environment variable DW_KODO_QUEUE_WORKERS), which defaults to 256; missing or non-positive values use this default. When the limit is reached, up to 128 additional requests may wait for at most 1s without reading their bodies. A position is released when request handling completes. When the waiting queue is full or a wait times out, registered DK-compatible endpoints return 503, and all other endpoints return 429. Both responses include Retry-After: 1, and these requests are not written to disk cache. This status-code distinction applies only to HTTP concurrency admission rejections; errors from subsequent forwarding and caching are unchanged. All requests with a body share the same concurrency limit; requests without a body do not count toward it. HTTP concurrency and Kodo workers share the configured count but are not bound to individual workers. Disabling the Kodo dispatch queue does not disable the HTTP concurrency limit. This limit does not guarantee a bound on total Pod memory.

When HTTP concurrency admission rejects an HTTP/1.x request, Dataway stops reading the remaining body and closes the connection after sending the response. Clients must establish a new connection when retrying.

Inbound HTTP requests use the following deadlines, independently of the downstream http_timeout:

Setting Default Purpose
http_read_timeout 5m Bounds the entire body upload, including request header reads for HTTP/1.x; continuously sending small chunks does not extend it
http_write_timeout 10m Sets the response write deadline, including upload and request processing time
http_idle_timeout 2m Bounds the idle wait for the next request on a persistent connection

Request body read timeouts return retryable 503 responses (dataway.httpBodyReadTimeout), release admission slots, and do not cache incomplete data. A streaming downstream may already have received part of the data; clients must still retry.

The request header read deadline remains 10s. The write deadline should exceed the read deadline plus expected processing time. These are network I/O deadlines and do not forcibly stop CPU computation.

RUM performs local token validation before reading the first body byte. Missing tokens or tokens rejected by local configuration immediately receive the corresponding authentication error. For HTTP/1.x, Dataway stops reading the remaining body and closes the connection without waiting for the upload deadline. Existing compatibility rules for allowed empty tokens, internal tokens, and secret tokens on non-sink requests remain unchanged. Aggregation and tail-sampling proxies return 502 (dataway.proxyFailed) when the backend connection fails; responses received from the backend retain their status codes, including empty responses.

All three settings must be positive. Non-positive YAML values and invalid or non-positive ENV values produce warnings and retain default deadlines; invalid YAML durations fail configuration loading. Increase read/write deadlines for legitimate large uploads or slow networks based on observed upload durations. See the Go HTTP Server documentation for deadline semantics.

DK-compatible endpoints are matched against the following list, not identified by token, query parameters, or User-Agent. Third-party clients calling the same endpoints also receive 503. The list must be maintained when DK adds endpoints; not every /v1/write/* endpoint is a DK endpoint.

Endpoint type returning 503 Paths
DK data categories /v1/write/{metric,metrics,network,keyevent,object,object_change,custom_object,logging,tracing,rum,security,profiling,dialtesting,siem_logging,langfuse-v2,agent_llm,dynamic_dw}; uses the category definitions from cliutils/point, including compatibility and reserved categories
DK special writes /v1/write/{heartbeat,bugreport,remote_job,dialtesting_browser_screenshot}
Replay and profiling /v1/write/rum/replay, /v1/write/rum/replay_assets, /v1/check/rum/replay_assets, /v1/upload/profiling
Aggregation and tail sampling /v1/aggregate, /v1/tail_sampling, /v1/tail_sampling_v2, /v1/tail_sampling_config, /v2/tail_sampling
OCSF ingestion /v1/ocsf_ingest
DK control endpoints /v1/datakit/usage_trace, /v1/datakit/pull, /v1/election, /v1/election/heartbeat, /v1/query/raw, /v1/workspace, /v1/object/labels, /v1/check/token/:token, /v1/env_variable, /v1/ntp, /v1/ping

Cloudflare's /v1/write/cf-logpush, AWS Firehose's /v1/input/firehose, OTLP's /otel/v1/*, Langfuse's /api/public/*, and other unlisted endpoints return 429 when admission is rejected. Health checks, configuration pulls, and other requests without a body still bypass the concurrency limit.

Env Description
DW_REMOTE_HOST
type: string
required: Y
Kodo address, or next Dataway address, format: http://host:port
DW_WHITE_LIST
type: string
required: N
Dataway client IP whitelist, comma-separated
DW_TRUSTED_PROXIES
type: string
required: N
Trusted proxy IPs/CIDRs, comma-separated. Forwarded client IP headers are used for whitelist checks only for requests from these proxies
DW_HTTP_TIMEOUT
type: string
required: N
Dataway request timeout to Kodo or next Dataway, default 3s
DW_HTTP_MAX_IDLE_CONN_PERHOST
type: int
required: N
Dataway maximum idle connections to Kodo Version-1.6.2
Default 1000 Version-1.11.2
DW_HTTP_READ_TIMEOUT
type: string
required: N
Inbound request read deadline; maps to http_read_timeout, default 5m
DW_HTTP_WRITE_TIMEOUT
type: string
required: N
Inbound response write deadline, including upload and handler time; maps to http_write_timeout, default 10m
DW_HTTP_IDLE_TIMEOUT
type: string
required: N
Inbound connection idle deadline while waiting for the next request; maps to http_idle_timeout, default 2m
DW_HTTP_MAX_CONN_PERHOST
type: int
required: N
Dataway maximum connections to Kodo, default unlimited Version-1.6.2
DW_KODO_QUEUE_ENABLED
type: boolean
required: N
Enable the bounded dispatch queue for write/upload/OTLP HTTP requests sent to Kodo or the next Dataway, default true
DW_KODO_QUEUE_WORKERS
type: int
required: N
Number of Kodo dispatch queue workers, default 256
DW_KODO_QUEUE_SIZE
type: int
required: N
Maximum number of requests waiting in the Kodo dispatch queue, default 1024
DW_KODO_QUEUE_MAX_BYTES
type: int/string
required: N
Maximum total request body bytes reserved by queued, in-flight, and waiting-to-enqueue Kodo queue requests. Supports values such as 1073741824, 1GB, or 1024MB; default 1GB
DW_KODO_QUEUE_ENQUEUE_TIMEOUT
type: string
required: N
Maximum time a request waits for a Kodo queue slot before Dataway caches eligible requests or returns 503 when cache is unavailable, default 100ms
DW_TOKEN_NEGATIVE_CACHE_ENABLED
type: boolean
required: N
Enable token negative cache. Entries are isolated by token, write API path, and main/headless mode; default true
DW_TOKEN_NEGATIVE_CACHE_TTL
type: string
required: N
Token negative cache TTL, default 5m
DW_TOKEN_NEGATIVE_CACHE_MAX_KEYS
type: int
required: N
Maximum number of scope keys kept in token negative cache, default 1000
DW_BIND
type: string
required: N
Dataway HTTP API IPv4 binding address, default 0.0.0.0:9528
DW_BIND_IPV6
type: string
required: N
Dataway HTTP API IPv6 binding address. IPv6 listening is disabled by default; set [::]:9528 to enable it
DW_API_LIMIT
type: int
required: N
Dataway API rate limiting, e.g., 1000 means each API can only be requested 1000 times per second, default 100K
DW_HEARTBEAT
type: string
required: N
Dataway heartbeat interval with center, default 60s
DW_MAX_HTTP_BODY_BYTES
type: int
required: N
Dataway API maximum allowed HTTP Body (in bytes), default 64MB
DW_TLS_INSECURE_SKIP_VERIFY
type: boolean
required: N
Ignore HTTPS/TLS certificate errors
DW_HTTP_CLIENT_TRACE
type: boolean
required: N
Dataway as HTTP client can enable related metrics collection, which will be output in its Prometheus metrics
DW_ENABLE_TLS
type: boolean
required: N
Enable HTTPS Version-1.4.1
DW_TLS_CRT
type: file-path
required: N
Specify HTTPS/TLS crt file directory Version-1.4.0
DW_TLS_KEY
type: file-path
required: N
Specify HTTPS/TLS key file directory Version-1.4.0
DW_SNI
type: string
required: N
Specify current Dataway SNI information Version-1.6.0
DW_DISABLE_404PAGE
type: boolean
required: N
Disable 404 page Version-1.6.1
DW_HTTP_IP_BLACKLIST_TTL
type: string
required: N
Set IP blacklist TTL, default 1m Version-1.11.0
DW_HTTP_IP_BLACKLIST_CLEAN_INTERVAL
type: string
required: N
Set IP blacklist cleanup interval, default 1h Version-1.11.0
HTTP TLS Settings

To generate a TLS certificate with a one-year validity period, you can use the following OpenSSL command:

# Generate a TLS certificate with a one-year validity
$ openssl req -new -newkey rsa:4096 -x509 -sha256 -days 365 -nodes -out tls.crt -keyout tls.key
...

After executing this command, the system will prompt you to enter some necessary information, including your country, region, city, organization name, department name, and your email address. This information will be included in your certificate.

After completing the information input, you will generate two files: tls.crt (certificate file) and tls.key (private key file). Please keep your private key file secure and safe.

In order for the application to use these TLS certificates, you need to set the absolute paths of these two files to the application's environment variables. Here is an example of setting environment variables:

DW_ENABLE_TLS must be turned on first, and then the other two ENVs (DW_TLS_CRT/DW_TLS_KEY) will take effect. Version-1.4.1

env:
- name: DW_ENABLE_TLS
  value: "true"
- name: DW_TLS_CRT
  value: "/path/to/your/tls.crt"
- name: DW_TLS_KEY
  value: "/path/to/your/tls.key"

Replace /path/to/your/tls.crt and /path/to/your/tls.key with the actual paths to your tls.crt and tls.key files, respectively.

After setting up the environment variables, you can test whether TLS is functioning correctly with the following command:

curl -k https://localhost:9528

If successful, you should see an ASCII art message indicating "It's working!" If the certificates are missing, you might encounter an error in the Dataway logs similar to:

server listen(TLS) failed: open /path/to/your/tls.{crt,key}: no such file or directory

In this case, Dataway would not start, and the curl command would also result in an error:

curl: (7) Failed to connect to localhost port 9528 after 6 ms: Couldn't connect to server

Ensure that the paths to the TLS certificate and key are correctly specified and that the files have the appropriate permissions for the application to read them.

Log Settings

Env Description
DW_LOG
type: string
required: N
Log path, defaults to log. Set to stdout to output logs to standard output for easier log collection
DW_LOG_LEVEL
type: string
required: N
Default is info, options include debug
DW_GIN_LOG
type: string
required: N
Default is gin.log, can also be set to stdout for easier collection
DW_LOG_PKG_ID
type: bool
required: N
Version-1.12.0 Enable log package id or not, default true

Token/UUID Settings

Env Description
DW_UUID
type: string
required: Y
Dataway UUID, generated by the system workspace when creating a new Dataway
DW_TOKEN
type: string
required: Y
Usually the data upload token of the system workspace
DW_SECRET_TOKEN
type: string
required: N
Can be set when Sinker functionality is enabled
DW_ENABLE_INTERNAL_TOKEN
type: boolean
required: N
Allow using __internal__ as client token, defaults to system workspace token
DW_ENABLE_EMPTY_TOKEN
type: boolean
required: N
Allow data upload without token, defaults to system workspace token

Sinker Settings

Env Description
DW_SECRET_TOKEN
type: string
required: N
Can be set when Sinker functionality is enabled
DW_CASCADED
type: string
required: N
Whether Dataway is cascaded
DW_SINKER_ETCD_URLS
type: string
required: N
etcd address list, comma-separated, e.g., http://1.2.3.4:2379,http://1.2.3.4:2380
DW_SINKER_ETCD_DIAL_TIMEOUT
type: string
required: N
etcd connection timeout, default 30s
DW_SINKER_ETCD_KEY_SPACE
type: string
required: N
etcd key name for Sinker configuration (default /dw_sinker)
DW_SINKER_ETCD_USERNAME
type: string
required: N
etcd username
DW_SINKER_ETCD_PASSWORD
type: string
required: N
etcd password
DW_SINKER_FILE_PATH
type: file-path
required: N
Specify sinker rule configuration via local file
DW_SINKER_CACHE_BUCKETS
type: int
required: N*
Version-1.11.0 Specifies the number of Sinker cache buckets, default 64
DW_SINKER_CACHE_RESERVED_CAPACITY
type: int
required: N*
Version-1.11.0 Specifies the maximum capacity of Sinker cache, default 1 million (1<<20)
DW_SINKER_CACHE_TTL
type: duration
required: N*
Version-1.11.0 Specifies the TTL of Sinker cache elements, default 10m (10 minutes)
DW_SINKER_CACHE_PREALLOC
type: bool
required: N*
Version-1.11.0 Pre-allocates cache memory, default false
Warning

If both local file and etcd methods are specified, the Sinker rules in the local file take priority.

Prometheus Metrics Exposure

Env Description
DW_PROM_URL
type: string
required: N
Prometheus metrics URL path (default /metrics)
DW_PROM_LISTEN
type: string
required: N
Prometheus metrics exposure address (default localhost:9090)
DW_PROM_DISABLED
type: boolean
required: N
Disable Prometheus metrics exposure
DW_PPROF_BIND
type: string
required: N
pprof listen address; disabled by default and accepts loopback only, for example localhost:6060

Disk Cache Settings

Env Description
DW_DISKCACHE_DIR
type: file-path
required: N
Set cache directory, this directory should generally be mounted storage
DW_DISKCACHE_DISABLE
type: boolean
required: N
Disable disk cache, if cache is not disabled, remove this environment variable
DW_DISKCACHE_CLEAN_INTERVAL
type: string
required: N
Cache cleanup interval, default 1s
DW_DISKCACHE_EXPIRE_DURATION
type: string
required: N
Cache expiration time, default 168h (7d)
DW_DISKCACHE_CAPACITY_MB
type: int
required: N
Version-1.6.0 Set available disk space size in MB, default 20GB
DW_DISKCACHE_BATCH_SIZE_MB
type: int
required: N
Version-1.6.0 Set maximum size of single disk cache file in MB, default 64MB
DW_DISKCACHE_MAX_DATA_SIZE_MB
type: int
required: N
Version-1.6.0 Set maximum size of single cache content (e.g., single HTTP body) in MB, default 64MB. Data packets exceeding this size will be discarded
Tips

Set DW_DISKCACHE_DISABLE to disable disk cache.

Performance Settings

Version-1.6.0

Env Description
DW_COPY_BUFFER_DROP_SIZE
type: int
required: N
HTTP body buffers exceeding specified size (in bytes) will be immediately cleared to avoid excessive memory consumption. Default 256KB

Dataway API List

Except for diagnostic and locally handled APIs, forwarding APIs validate tokens according to their own rules and forward requests to Kodo or the next Dataway. See the Langfuse compatibility API section below for its authentication behavior.

GET /v1/ping

Version-1.11.0

  • API description: Get current dataway version and release date, also return the public IP address of your request

If 404 page disabled(disable_404page), this API not working.

GET /v1/ntp

Version-1.6.0

  • API description: Get current Dataway unix timestamp(unit: second)

POST /v1/write/:category

  • API description: Receive various collection data uploaded by Datakit
  • Downstream 4xx: Ordinary writes and OCSF forwarding share error handling that preserves the HTTP status. A 404 response returns {}. For other 4xx responses, Dataway extracts error_code from a JSON error body it can decode and omits other error details. An empty body, a non-JSON body, or an undecodable error_code results in {}; failure to decode an error body no longer changes a 4xx response to 500. Downstream 4xx responses do not trigger disk caching.

POST /v1/ocsf_ingest

Accepts OCSF JSON, converts events into logging points on the current Dataway node, and writes them to the fixed ocsf index through /v1/write/logging, without requiring aggregation or tail sampling to be enabled.

  • Requests use Content-Type: application/json; charset parameters are accepted. Uncompressed bodies, Content-Encoding: identity, and gzip are supported. NDJSON and other compression encodings are not supported.
  • Supports a single event object, an event array, or an {"events":[...]} bundle. A top-level object containing class_uid is treated as a single event; otherwise it is treated as a bundle. Outer bundle metadata does not produce points; the point count reflects the actual events.
  • Authentication runs before reading the body. Token precedence is the token query parameter, X-Token, then X-Amz-Firehose-Access-Key. Empty tokens, internal tokens, and secret tokens follow existing configuration and sink compatibility rules.
  • Each event must contain a SemVer 1.x metadata.version, a non-negative integer class_uid, and an integer millisecond time. The timestamp must fit in int64 after conversion to nanoseconds. A batch may mix 1.x versions and event classes. Full OCSF Schema validation and external Schema service requests are not performed.
  • The request body, decompressed gzip JSON, and converted protobuf batch are each subject to max_http_body_bytes (DW_MAX_HTTP_BODY_BYTES), default 64 MiB. Exceeding a limit rejects the entire batch with 413; the sender must reduce the batch size. Dataway does not split batches automatically.

Point mapping and field limits

Each event produces one point with measurement/source ocsf, its timestamp taken from the event's time, and logging status fixed to info. The original OCSF severity and event outcome do not change the logging level.

Input Output
Complete original event JSON message
Top-level message/status/source/date ocsf_message/ocsf_status/ocsf_source/ocsf_date
Top-level time Point timestamp in nanoseconds; the original millisecond value remains in message
Other strings, booleans, and numbers Fields with the same names; integers use int64, large non-negative integers may use uint64, and decimal or exponent forms use float64. Out-of-range values return 400
Nested objects Fields with dotted paths, such as src_endpoint.ip; dots in original key names are preserved
Arrays JSON string fields
null and empty objects No separate field; preserved in the original JSON

Each point supports at most 1024 fields, including the generated message and status. Final field names are limited to 256 bytes, and individual string values to 32 MiB, including message. Exceeding a limit rejects the entire batch with 413; fields and values are not truncated automatically.

Requests and responses

Example OCSF 1.3.0 Authentication event:

curl -X POST 'https://dataway.example.com/v1/ocsf_ingest?token=<token>' \
  -H 'Content-Type: application/json' \
  --data-binary '{"metadata":{"version":"1.3.0","product":{"name":"example","vendor_name":"example"}},"class_uid":3002,"category_uid":3,"type_uid":300201,"activity_id":1,"severity_id":1,"time":1713632701123,"user":{"name":"alice"},"service":{"name":"ssh"}}'

This request produces one point named ocsf with timestamp 1713632701123000000, fields user.name=alice and service.name=ssh, and the complete message. Any caller-specified X-Storage-Index-Name is overridden with ocsf; cache replay retains that index.

Dataway validates and converts the entire batch before sending it synchronously through the existing Kodo, sink, signing, cache, and replay paths:

Status code Meaning
200 Downstream delivery succeeded; the body is empty when the downstream response is empty
200 + {"error_code":"dataway.cached"} Successfully cached for later replay; this does not indicate a completed downstream write
400 Empty body/batch, invalid JSON/event, out-of-range number, or field mapping conflict
413 Request body, protobuf, or field limit exceeded
415 Unsupported media type or compression encoding
503 Concurrency admission rejected or request body read timed out

Authentication errors and delivery failures that cannot be cached follow the existing paths. This endpoint adds no asynchronous ingestion queue and does not guarantee deduplication or atomic downstream batch writes. Existing HTTP metrics report ingress status and latency; send and cache metrics use /v1/write/logging.

Duplicate JSON keys and field conflicts

When a key occurs more than once within the same JSON object, the value of its last occurrence in the original request is retained. Duplicate keys alone do not cause a 400 response. This rule applies to the outer bundle, event objects, nested objects, and objects inside arrays; separate objects do not overwrite each other. Keys are compared after decoding JSON escapes; for example, class_uid and class\u005fuid are treated as the same name. If a repeated key has an object or array value, the later value replaces the earlier value entirely; values are not merged.

Field validation and point mapping use the final retained values. The point's message preserves the complete original event JSON, including duplicate keys and their original values; it is not replaced with deduplicated JSON. If a final retained value violates a field requirement, such as a negative class_uid, the entire batch still returns 400 for an invalid event.

The following single-event request passes conversion validation and produces one point with class_uid=4001 and user.name=bob. Its message retains the complete original JSON below:

{
  "metadata": {"version": "1.3.0"},
  "class_uid": 3002,
  "class_uid": 4001,
  "time": 1713632701123,
  "user": {"name": "alice", "name": "bob"}
}

Field conflicts caused by renaming or flattening into dotted paths still reject the entire batch with 400, and no points are sent. For example, in {"a.b":1,"a":{"b":2}}, two distinct paths both become a.b after flattening, causing a field mapping conflict. The error description identifies the conflicting field path and the event's position in the batch (starting at 1).

POST /v1/aggregate

  • API description: Receives aggregated metric data. This route is registered only when the aggregate feature is initialized successfully.
  • For the operating modes, configuration, and request requirements, see Dataway Metric Aggregation.

POST /v1/tail_sampling, POST /v1/tail_sampling_v2, POST /v2/tail_sampling, and POST /v1/tail_sampling_config

  • API description: /v1/tail_sampling accepts raw tail-sampling packets and also accepts headerless zstd packets sent by Datakit 2.10; the legacy /v1/tail_sampling_v2 path accepts raw packets only; /v2/tail_sampling accepts zstd packets with the compression-negotiation header; /v1/tail_sampling_config accepts tail-sampling configuration. These routes are registered only when the tail-sampling feature is initialized successfully.
  • For the operating modes, configuration, and request requirements, see Dataway Tail Sampling.

POST /otel/v1/{traces,metrics,logs}

Version-1.17.0

  • API description: Receive OpenTelemetry OTLP HTTP/protobuf data and forward it to the matching Kodo path without rewriting the payload.
  • Supported paths:
    • POST /otel/v1/traces
    • POST /otel/v1/metrics
    • POST /otel/v1/logs
  • Request requirements:

    • Content-Type must be application/x-protobuf; media type parameters are accepted, for example application/x-protobuf; charset=utf-8
    • The workspace token can be provided through the token query, the X-Token header, or Authorization: Bearer <token>; Bearer tokens are converted to X-Token before forwarding
    • When using OpenTelemetry SDK/Agent environment variables, explicitly configure OTLP HTTP/protobuf and set the base endpoint to the Dataway /otel prefix; OpenTelemetry appends /v1/traces, /v1/metrics, and /v1/logs for each signal:
    export OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
    export OTEL_EXPORTER_OTLP_LOGS_ENDPOINT=https://dataway.example.com/otel/v1/logs
    export OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=https://dataway.example.com/otel/v1/traces
    export OTEL_EXPORTER_OTLP_METRICS_ENDPOINT=https://dataway.example.com/otel/v1/metrics
    export OTEL_EXPORTER_OTLP_HEADERS="Authorization=Bearer%20{token}"
    
    • If per-signal endpoints are used, configure the full Dataway paths, for example OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=https://dataway.example.com/otel/v1/traces, OTEL_EXPORTER_OTLP_METRICS_ENDPOINT=https://dataway.example.com/otel/v1/metrics, and OTEL_EXPORTER_OTLP_LOGS_ENDPOINT=https://dataway.example.com/otel/v1/logs
    • Startup options have the same meaning as the environment variables. For example, with the Java Agent, configure -Dotel.exporter.otlp.protocol=http/protobuf, -Dotel.exporter.otlp.endpoint=https://dataway.example.com/otel, and -Dotel.exporter.otlp.headers=Authorization=Bearer%20{token}. If an implementation handles the encoded space in the Authorization header differently, use OTEL_EXPORTER_OTLP_HEADERS="X-Token={token}" or the matching startup option instead.
    • Dataway does not parse or rewrite the OTLP body; /otel/v1/metrics is not converted into /v1/write/metric line protocol. Kodo parses it with DataKit's default OTLP metrics rules: the measurement is otel_service, and metric field names keep the original OTLP metric names, for example runtime.jvm.memory is not rewritten to runtime_jvm_memory
    • Kodo's raw OTLP response status, response body, and required response headers are passed through; when forwarding fails and matches the disk-cache policy, the request enters Dataway disk-cache replay

GET /v1/datakit/pull

  • API description: Handles Datakit pull center configuration (blacklist/pipeline) requests

POST /v1/datakit/usage_trace

  • API description: Receives Datakit usage tracing data.

POST /v1/write/rum/replay

  • API description: Receive Session Replay data uploaded by Datakit

POST /v1/write/rum/replay_assets

  • API description: Receives Session Replay asset upload requests.

POST /v1/check/rum/replay_assets

  • API description: Checks whether a Session Replay asset already exists.

POST /v1/upload/profiling

  • API description: Receive profiling data uploaded by Datakit

POST /v1/input/firehose

  • API description: Receives Firehose input data.

POST /v1/election

  • API description: Handles election requests for Datakit

POST /v1/election/heartbeat

  • API description: Handles election heartbeat requests for Datakit

POST /v1/query/raw

  • API description: Handles DQL query requests initiated by the Datakit side

POST /v1/workspace

  • API description: Handles workspace query requests initiated by Datakit

GET /v1/env_variable

  • API description: Retrieves workspace environment variables.

POST /v1/dataway/heartbeat

  • API description: Receives Dataway heartbeat reports.

POST /v1/object/labels

  • API description: Handles requests to modify object labels

DELETE /v1/object/labels

  • API description: Handles delete object Label requests

GET /v1/check/token/:token

  • API description: Checks whether a token is valid.

Langfuse Compatibility APIs

The following APIs are provided for Langfuse client compatibility. Dataway forwards these requests upstream without token validation:

  • POST /api/public/otel/v1/traces: Receives Langfuse OTLP trace data.
  • GET /api/public/projects: Retrieves Langfuse project information.
  • POST /api/public/ingestion: Receives Langfuse ingestion data. When the upstream accepts a batch but returns an empty body, Dataway builds a Langfuse SDK 4.x-compatible successes/errors JSON response from the event IDs in the request batch.

Dataway metrics collection

HTTP client metrics collection

If you want to collect metrics for Dataway HTTP requests to Kodo (or Dataway next hop), you need to manually enable the http_client_trace configuration. You can also specify DW_HTTP_CLIENT_TRACE=true during the installation phase.

Dataway itself exposes Prometheus metrics, which can be collected through Datakit's built-in prom collector, which is configured as follows:

[[inputs.prom]]
  ## Exporter URLs.
  urls = [ "http://localhost:9090/metrics", ]

  source = "dataway"

  election = true

  ## Dataway metric set fixed to dw, do not change
  measurement_name = "dw"

You can add annotations on pods (requires [Datakit 1.14.2] (../datakit/changelog.md#cl-1.14.2) or above):

annotations:
   datakit/prom.instances: |
     [[inputs.prom]]
       url = "http://$IP:9090/metrics" # Here the port (default 9090) is as appropriate
       source = "dataway"
       measurement_name = "dw" # pinned to this metric set
       interval = "30s"

       [inputs.prom.tags]
         namespace = "$NAMESPACE"
         pod_name = "$PODNAME"
         node_name = "$NODENAME"

If the collection is successful, search for dataway in the "Scene"/"Built-in View" of the Guance to see the corresponding monitoring view.

Cache and Kodo Queue Troubleshooting

When Kodo returns 5xx, Dataway fails to send a request to Kodo, or the Kodo dispatch queue is full, Dataway tries to write eligible requests into the disk cache. Kodo 4xx responses are not cached.

Use these metrics first when troubleshooting:

  • dataway_http_api_cached_bytes{reason=...}: the request was written to cache. Common reason values include Kodo 5xx status text, httpCliDoFailed, and kodoQueueFull.
  • dataway_http_api_dropped_cache{reason=...}: Dataway tried to cache the request but did not write it. Common reason values include feat-disabled, expected-api-drop, body-md5-not-matched, body-length-not-matched, expired, put-failed, and sendopt-nil.
  • dataway_kodo_queue_full_total{action=...}: how Dataway handled a full Kodo queue. action="cache" means the request was moved to cache; action="reject" means Dataway returned 503 after cache was unavailable or cache write failed.
  • dataway_http_concurrency_in_flight / dataway_http_concurrency_waiting: current requests admitted for processing and requests still waiting before their bodies are read.
  • dataway_http_concurrency_requests_total{result=...}: HTTP concurrency outcomes, including admitted, waiting_full, wait_timeout, and canceled.

Dataway Metric List

The following are the indicators exposed by Dataway, which can be obtained by requesting http://localhost:9090/metrics, and you can view (3s) a specific indicator in real time by following the following command:

If some metrics cannot be queried, it may be caused by the relevant business module not running.

watch -n 3 'curl -s http://localhost:9090/metrics | grep -a <METRIC-NAME>'
TYPE NAME LABELS HELP
SUMMARY dataway_kodo_queue_wait_seconds api,method Kodo queue wait duration before worker dispatch
SUMMARY dataway_http_concurrency_wait_seconds api,method,result HTTP concurrency wait duration
GAUGE dataway_http_concurrency_in_flight N/A Current HTTP requests being processed
GAUGE dataway_http_concurrency_waiting N/A Current HTTP requests waiting before their request bodies are read
COUNTER dataway_http_concurrency_requests_total api,method,result HTTP concurrency results
SUMMARY dataway_http_api_elapsed_seconds api,method,sinked,status API request latency
SUMMARY dataway_http_api_body_buffer_utilization api API body buffer utillization(Len/Cap)
SUMMARY dataway_http_api_body_copy api API body copy
SUMMARY dataway_http_api_body_copy_seconds api API body copy latency
SUMMARY dataway_http_api_body_copy_enlarge api API body copy enlarged pooled buffer
SUMMARY dataway_http_api_resp_size_bytes api,method,status API response size
SUMMARY dataway_http_api_req_size_bytes api,method,status API request size
COUNTER dataway_http_api_body_too_large_dropped_total api,method API request too large dropped
COUNTER dataway_http_api_with_inner_token api,method API request with inner token
COUNTER dataway_http_api_dropped_total api,method API request dropped when sinker rule match failed
COUNTER dataway_ip_blacklist_blocked_total api,method IP blacklist blocked requests total
COUNTER dataway_ip_blacklist_missed_total api,method IP blacklist missed total
COUNTER dataway_ip_blacklist_added_total api,method,reason IP blacklist added total
COUNTER dataway_syncpool_stats name,type sync.Pool usage stats
COUNTER dataway_http_api_copy_body_failed_total api API copy body failed count
COUNTER dataway_http_api_signed_total api,method API signature count
SUMMARY dataway_http_api_cached_bytes api,cache_type,method,reason API cached body bytes
SUMMARY dataway_http_api_reusable_body_read_bytes api,method API re-read body on forking request
SUMMARY dataway_http_api_recv_points api API /v1/write/:category recevied points
SUMMARY dataway_http_api_send_points api API /v1/write/:category send points
SUMMARY dataway_http_api_cache_points api,cache_type Disk cached /v1/write/:category points
SUMMARY dataway_http_api_cache_cleaned_points api,cache_type,status Disk cache cleaned /v1/write/:category points
COUNTER dataway_http_api_forked_total api,method,token API request forked total
GAUGE dataway_http_cli_info max_conn_per_host,max_idle_conn,max_idle_conn_per_host,timeout Dataway as client settings
GAUGE dataway_http_info cascaded,docker,http_client_trace,listen,max_body,release_date,remote,version Dataway API basic info
GAUGE dataway_kodo_queue_depth N/A Current Kodo dispatch queue depth including in-flight tasks
GAUGE dataway_kodo_queue_bytes N/A Current Kodo dispatch queue body bytes including in-flight tasks
COUNTER dataway_kodo_queue_enqueued_total api,method Kodo queue enqueued tasks
COUNTER dataway_kodo_queue_full_total api,method,action Kodo queue full events
COUNTER dataway_kodo_queue_dispatch_total api,method,status Kodo queue dispatch results
COUNTER dataway_token_negative_cache_added_total api,method,error_code Token negative cache added total
COUNTER dataway_token_negative_cache_blocked_total api,method,error_code Token negative cache blocked requests total
GAUGE dataway_last_heartbeat_time N/A Dataway last heartbeat with Kodo timestamp
SUMMARY dataway_http_api_copy_buffer_drop_total max API copy buffer dropped(too large cached buffer) count
GAUGE dataway_cpu_usage N/A Dataway CPU usage(%)
GAUGE dataway_mem_stat type Dataway memory usage stats
GAUGE dataway_open_files N/A Dataway open files
GAUGE dataway_open_files_by_type type Dataway open files grouped by fd type
GAUGE dataway_tcp_connections direction,port,state Dataway TCP connections grouped by direction, port and state(Linux only)
GAUGE dataway_cpu_cores N/A Dataway CPU cores
GAUGE dataway_uptime N/A Dataway uptime
COUNTER dataway_process_ctx_switch_total type Dataway process context switch count(Linux only)
COUNTER dataway_process_io_count_total type Dataway process IO count
COUNTER dataway_process_io_bytes_total type Dataway process IO bytes count
SUMMARY dataway_http_api_dropped_cache api,method,reason Dropped cache data dur to various reasons
COUNTER dataway_http_api_body_size_bytes_total api,token Accumulated API body bytes for aggregate or tailSampling
COUNTER dataway_http_aggr_point_total api,token point count of aggregate or tailSampling
COUNTER dataway_http_tail_sampling_trace_total token tailSampling trace count
COUNTER dataway_http_tail_sampling_span_total token tailSampling span count
COUNTER dataway_http_tail_sampling_packet_send_total token,data_type,result tailSampling packet send result count
GAUGE dataway_httpcli_dns_resolved_address api,coalesced,host,server HTTP DNS resolved address
SUMMARY dataway_httpcli_dns_cost_seconds api,coalesced,host,server HTTP DNS cost
SUMMARY dataway_httpcli_tls_handshake_seconds api,server HTTP TLS handshake cost
SUMMARY dataway_httpcli_http_connect_cost_seconds api,server HTTP connect cost
SUMMARY dataway_httpcli_got_first_resp_byte_cost_seconds api,server Got first response byte cost
SUMMARY http_latency api,server HTTP latency
COUNTER dataway_httpcli_tcp_conn_total api,server,remote,type HTTP TCP connection count
COUNTER dataway_httpcli_conn_reused_from_idle_total api,server HTTP connection reused from idle count
SUMMARY dataway_httpcli_conn_idle_time_seconds api,server HTTP connection idle time
GAUGE dataway_sinker_rule_cache_size name Sinker rule cache size
GAUGE dataway_sinker_rule_error error Rule errors
GAUGE dataway_sinker_default_rule_hit info Default sinker rule hit count
GAUGE dataway_sinker_rule_last_applied_time source,version Rule last applied time(Unix timestamp)
SUMMARY dataway_sinker_rule_cost_seconds type Rule cost time seconds
SUMMARY dataway_sinker_lru_cache_cleaned name Sinker LRU cache cleanup removed entries
COUNTER dataway_sinker_lru_cache_dropped_total bucket,name,reason Total entries evicted from the Sinker LRU cache
HISTOGRAM dataway_sinker_lru_cache_expired_delay_seconds bucket,name Cleanup delay for expired entries in the Sinker LRU cache
HISTOGRAM dataway_sinker_lru_cache_evicted_remaining_ttl_seconds bucket,name Remaining TTL of entries evicted due to the Sinker LRU cache capacity limit
COUNTER dataway_sinker_pull_total event,source Sinker pulled or pushed total
GAUGE dataway_sinker_rule_count type,with_default Sinker rule count
GAUGE dataway_sinker_rule_cache_get_total name,type Sinker rule cache get hit/miss count
COUNTER diskcache_rotate_total path Cache rotate count, mean file rotate from data to data.0000xxx
COUNTER diskcache_remove_total path Removed file count, if some file read EOF, remove it from un-read list
COUNTER diskcache_wakeup_total path Wakeup count on sleeping write file
COUNTER diskcache_pos_updated_total op,path .pos file updated count
COUNTER diskcache_seek_back_total path Seek back when Get() got any error
GAUGE diskcache_capacity path Current capacity(in bytes)
GAUGE diskcache_max_data path Max data to Put(in bytes), default 0
GAUGE diskcache_batch_size path Data file size(in bytes)
GAUGE diskcache_size path Current cache size that waiting to be consumed(get). The size include header bytes
GAUGE diskcache_open_time no_fallback_on_error,no_lock,no_pos,no_sync,path Current cache Open time in unix timestamp(second)
GAUGE diskcache_last_close_time path Current cache last Close time in unix timestamp(second)
GAUGE diskcache_datafiles path Current un-read data files
HISTOGRAM diskcache_lock_wait_seconds lock_type,path Time spent waiting for locks by lock type
COUNTER diskcache_lock_contention_total lock_type,path Number of lock contention events
SUMMARY diskcache_get_latency path Get() cost seconds
SUMMARY diskcache_put_latency path Put() cost seconds
SUMMARY diskcache_put_bytes path Cache Put() bytes
SUMMARY diskcache_get_bytes path Cache Get() bytes
SUMMARY diskcache_dropped_data path,reason Dropped data during Put() when capacity reached.

Metrics under Docker

There are two modes for non-Kubernetes, host mode and Docker mode. This section will specifically discuss the differences in metrics collection when installing in Docker.

When installed in docker, the HTTP port that exposes metrics will be mapped to port 19090 on the host machine (by default). In this case, the metrics collection address is http://localhost:19090/metrics.

If a different port is specified, the installer will add 10000 to the specified port during installation. Therefore, the specified port should not exceed 45535.

pprof is disabled by default, and Docker installations do not publish a profiling port to the host. For temporary diagnosis, explicitly set pprof_bind or DW_PPROF_BIND to localhost:6060, then collect through docker exec, kubectl exec, or a controlled port forward. Non-loopback addresses are rejected.

Dataway's Own Log Collection and Processing

Dataway's own logs are divided into two categories: one is the gin log, and the other is the Dataway's own log. The following Pipeline can separate them:

# Pipeline for dataway logging

# Testing sample loggin
'''
2023-12-14T11:27:06.744+0800    DEBUG   apis    apis/api_upload_profile.go:272  save profile file to disk [ok] /v1/upload/profiling?token=****************a4e3db8481c345a94fe5a
[GIN] 2021/10/25 - 06:48:07 | 200 |   30.890624ms |  114.215.200.73 | POST     "/v1/write/logging?token=tkn_5c862a11111111111111111111111"
'''

add_pattern("TOKEN", "tkn_\\w+")
add_pattern("GINTIME", "%{YEAR}/%{MONTHNUM}/%{MONTHDAY}%{SPACE}-%{SPACE}%{HOUR}:%{MINUTE}:%{SECOND}")
grok(_,"\\[GIN\\]%{SPACE}%{GINTIME:timestamp}%{SPACE}\\|%{SPACE}%{NUMBER:dataway_code}%{SPACE}\\|%{SPACE}%{NOTSPACE:cost_time}%{SPACE}\\|%{SPACE}%{NOTSPACE:client_ip}%{SPACE}\\|%{SPACE}%{NOTSPACE:method}%{SPACE}%{GREEDYDATA:http_url}")

# gin logging
if cost_time != nil {
  if http_url != nil  {
    grok(http_url, "%{TOKEN:token}")
    cover(token, [5, 15])
    replace(message, "tkn_\\w{0,5}\\w{6}", "****************$4")
    replace(http_url, "tkn_\\w{0,5}\\w{6}", "****************$4")
  }

  group_between(dataway_code, [200,299], "info", status)
  group_between(dataway_code, [300,399], "notice", status)
  group_between(dataway_code, [400,499], "warning", status)
  group_between(dataway_code, [500,599], "error", status)

  if sample(0.1) { # drop 90% debug log
    drop()
    exit()
  } else {
    set_tag(sample_rate, "0.1")
  }

  parse_duration(cost_time)
  duration_precision(cost_time, "ns", "ms")

  set_measurement('gin', true)
  set_tag(service,"dataway")
  exit()
}

# app logging
if cost_time == nil {
  grok(_,"%{TIMESTAMP_ISO8601:timestamp}%{SPACE}%{NOTSPACE:status}%{SPACE}%{NOTSPACE:module}%{SPACE}%{NOTSPACE:code}%{SPACE}%{GREEDYDATA:msg}")
  if level == nil {
    grok(message,"Error%{SPACE}%{DATA:errormsg}")
    if errormsg != nil {
      add_key(status,"error")
      drop_key(errormsg)
    }
  }
  lowercase(level)

  # if debug level enabled, drop most of them
  if status == 'debug' {
    if sample(0.1) { # drop 90% debug log
      drop()
      exit()
    } else {
      set_tag(sample_rate, "0.1")
    }
  }

  group_in(status, ["error", "panic", "dpanic", "fatal","err","fat"], "error", status) # mark them as 'error'

  if msg != nil {
    grok(msg, "%{TOKEN:token}")
    cover(token, [5, 15])
    replace(message, "tkn_\\w{0,5}\\w{6}", "****************$4")
    replace(msg, "tkn_\\w{0,5}\\w{6}", "****************$4")
  }

  set_measurement("dataway-log", true)
  set_tag(service,"dataway")
}

Dataway Bug Report

Dataway exposes metrics and can temporarily enable a profiling endpoint for troubleshooting. pprof is disabled by default; set pprof_bind to a loopback address before collection and disable it again afterward.

Use the actual configured addresses and ports when collecting the following information.

dw-bug-report.sh
br_dir="dw-br-$(date +%s)"
mkdir -p $br_dir

echo "Save bug report to ${br_dir}"

# Modify the following configurations according to your actual situation
dw_ip="localhost" # The IP address where Dataway's metrics/profile is exposed
metric_port=9090  # The port where metrics are exposed
profile_port=6060 # Explicitly enable the localhost:6060 pprof listener first
dw_yaml_conf="/usr/local/cloudcare/dataflux/dataway/dataway.yaml"
dw_dot_yaml_conf="/usr/local/cloudcare/dataflux/dataway/.dataway.yaml"

# Collect runtime metrics
curl -v "http://${dw_ip}:${metric_port}/metrics" -o $br_dir/metrics

# Collect profiling information
curl -v "http://${dw_ip}:${profile_port}/debug/pprof/allocs" -o $br_dir/allocs
curl -v "http://${dw_ip}:${profile_port}/debug/pprof/heap" -o $br_dir/heap
curl -v "http://${dw_ip}:${profile_port}/debug/pprof/profile" -o $br_dir/profile # This command will take about 30 seconds to run

cp $dw_yaml_conf $br_dir/dataway.yaml.copy
cp $dw_dot_yaml_conf $br_dir/.dataway.yaml.copy

tar czvf ${br_dir}.tar.gz ${br_dir}
rm -rf ${br_dir}

Run the script:

$ sh dw-bug-report.sh
...

After execution, a file similar to dw-br-1721188604.tar.gz will be generated. You can then retrieve this file for further use.

FAQ

Request Entity Too Large Issue

Version-1.3.7

Dataway has a default setting for the size of the request body (default is 64MB), but when the request body is too large, the client will receive an HTTP 413 error (Request Entity Too Large). If the request body is within a reasonable range, you can appropriately increase this value (unit is bytes):

  • Set the environment variable DW_MAX_HTTP_BODY_BYTES for Kubernetes Pod install
  • In dataway.yaml, set max_http_body_bytes for host install

If there is a request that is too large during runtime, it is reflected in both metrics and logs:

  • The metric dataway_http_too_large_dropped_total exposes the number of discarded large requests
  • Search the Dataway logs with cat log | grep 'drop too large request'. The logs will output the details of the HTTP request Header, which is helpful for further understanding the client situation
Warning

In the disk cache module, there is also a maximum data block write limit (default 64MB). If you increase the maximum request body configuration, you should also adjust this configuration accordingly (ENV_DISKCACHE_MAX_DATA_SIZE), to ensure that large requests can be correctly written to the disk cache.


  1. This limite will cause Dataway's performance decline. Under high payload, we should increase CPU limit or add more Dataway instances. ↩

Feedback

Is this page helpful?