epok

Migration Guide

Updated May 31, 2026 · today

Move from Datadog, Splunk, or Loki without rewriting your log pipeline. Ship to both for a day, verify parity, then cut over.

Cutover Principles

The three rules that make migration boring (the way migrations should be):

  1. 1. Dual-ship first.

    Keep your current tool running. Send the same logs to Epok for 24–48 hours. Compare dashboards and alerts. Only flip the switch once you've verified parity.

  2. 2. Move alerts before dashboards.

    Alerts are what wake people up. Rebuild alerting in Epok first, verify it's firing on the right incidents, then migrate dashboards at your own pace. Dashboards can live in both tools for weeks.

  3. 3. Don't try to port everything.

    Most legacy alert rules exist to paper over the absence of anomaly detection. Epok detects spikes, drops, new errors, golden-signal regressions, and K8s failures automatically. Keep only the threshold rules that encode hard business constraints (e.g. "payment success rate must stay above 99.9%").

From Datadog

Datadog Logs uses its own intake protocol. Epok doesn't emulate it; the migration path is the Datadog Agent's built-in Vector/OTLP forwarder — or swap the Agent for Vector directly.

Cutover steps

  1. Keep the Datadog Agent running (or install Vector alongside).
  2. Add a second pipeline in Vector that reads from `datadog_agent` and writes to Epok's Elasticsearch Bulk API.
  3. Verify parity for 24–48 hours: search the same time window in both tools.
  4. Flip alerts service-by-service. Move dashboards last.
  5. Uninstall the Datadog Agent once you've retired all dashboards and monitors.

Config

vector.toml
toml
# vector.toml — Datadog → Epok dual-shipping shim

[sources.ddagent]
type = "datadog_agent"
address = "0.0.0.0:8080"

[sinks.epok]
type = "elasticsearch"
inputs = ["ddagent"]
endpoint = "https://ingest.getepok.dev"
bulk.index = "logs"

[sinks.epok.auth]
strategy = "basic"
user = "YOUR_EPOK_API_KEY"
password = "x"

# Optional: keep sending to Datadog during the cutover window.
[sinks.datadog]
type = "datadog_logs"
inputs = ["ddagent"]
default_api_key = "YOUR_DATADOG_API_KEY"

Gotchas

  • Datadog tags (`service:api`, `env:prod`) come through as top-level fields — Epok handles them natively, no remapping needed.
  • Datadog's `@source` and `@reserved` attributes are dropped by the Elasticsearch sink. Keep them by adding a `remap` transform if your alerts depend on them.
  • Datadog's dedup/rehydration features don't exist in Epok — anomaly detection runs continuously, so you don't need them.

From Splunk

Splunk HEC is a proprietary wire protocol. Epok provides a Vector-based shim: your app keeps sending HEC events; Vector translates them to Epok's Elasticsearch Bulk API in-flight.

Cutover steps

  1. Install Vector on the same host as your existing Heavy Forwarder (or anywhere HEC traffic can reach).
  2. Configure Vector's `splunk_hec_logs` source with your existing HEC token — apps keep their Splunk config unchanged.
  3. Sink into Epok's Elasticsearch Bulk API.
  4. Cutover gradually: point half your forwarders at the Vector shim, watch Epok, then move the rest.
  5. Retire Splunk indexers on your own schedule — no hard deadline.

Config

vector.toml
toml
# vector.toml — Splunk HEC → Epok

[sources.splunk_in]
type = "splunk_hec_logs"
address = "0.0.0.0:8088"
token = "YOUR_EXISTING_HEC_TOKEN"

[sinks.epok]
type = "elasticsearch"
inputs = ["splunk_in"]
endpoint = "https://ingest.getepok.dev"
bulk.index = "logs"

[sinks.epok.auth]
strategy = "basic"
user = "YOUR_EPOK_API_KEY"
password = "x"

Gotchas

  • Splunk `sourcetype` and `host` become top-level fields in Epok — equivalent to `service` and `host` on the Epok side.
  • SPL (Splunk Search Processing Language) → LogsQL: most searches translate 1:1. `index=main error | stats count by host` becomes `error | stats count() by (host)`.
  • Splunk's `| lookup` and `| inputlookup` don't have direct equivalents; reproduce with saved searches and facet filtering.

From Grafana Loki

Easiest migration. Epok speaks native Loki push — no shim required. Point your existing Promtail, Grafana Alloy, or FluentBit clients at Epok and you're done.

Cutover steps

  1. Update your shipper's endpoint to `https://ingest.getepok.dev/loki/api/v1/push`.
  2. Use Basic Auth: username = your Epok API key, password = any string.
  3. Dual-ship to Loki and Epok for 24 hours to verify.
  4. Flip alerts and dashboards to Epok. Loki can be retired on your own schedule.

Config

config.yaml
toml
# Promtail / Grafana Alloy / FluentBit — same config, new URL + auth.

# promtail.yaml
clients:
  - url: https://ingest.getepok.dev/loki/api/v1/push
    basic_auth:
      username: YOUR_EPOK_API_KEY
      password: x

# grafana-alloy (alloy.river)
loki.write "epok" {
  endpoint {
    url = "https://ingest.getepok.dev/loki/api/v1/push"
    basic_auth {
      username = "YOUR_EPOK_API_KEY"
      password = "x"
    }
  }
}

Gotchas

  • Loki labels map to Epok stream fields. `{app="api",env="prod"}` becomes searchable as `service:api AND env:prod` in LogsQL.
  • Loki queries use LogQL; Epok uses LogsQL. Close cousins — most LogQL expressions translate with minor syntax tweaks.
  • Ruler rules don't port automatically. Rewrite them as Epok threshold rules or let anomaly detection replace them.

Stuck mid-migration?

Email support@getepok.dev. We'll help you translate alert rules, verify dual-shipping, and retire your old tooling on whatever schedule fits your team.

← Back to Docs