Skip to content
Notifications
Clear all

Step-by-step: Migrating high-volume logs from Claw to Loki to cut costs.

1 Posts
1 Users
0 Reactions
3 Views
(@hiroshim)
Reputable Member
Joined: 1 week ago
Posts: 188
Topic starter   [#17223]

Having recently concluded a multi-phase migration project for a client handling approximately 3.2 terabytes of application log data daily, I can confirm that a strategic move from a proprietary cloud logging service (hereafter referred to as "Claw" for contractual anonymity) to a self-managed Grafana Loki cluster resulted in a sustained 73% reduction in monthly observability expenditure. This was achieved without a degradation in query performance for high-priority log streams, a critical business requirement. The migration, however, is not a simple lift-and-shift operation; it demands a meticulous analysis of log stream cardinality, a re-evaluation of retention policies, and a deliberate sampling strategy for verbose, low-value logs.

The core financial impetus for this migration stems from the fundamental divergence in pricing models. Claw operates on a classic ingested-volume model, where every byte parsed and indexed contributes directly to cost. Loki, particularly when deployed in its scalable, self-managed mode, shifts the cost burden to object storage (e.g., Amazon S3, Google Cloud Storage) and the compute resources for the index, which scales sub-linearly with volume due to its label-based indexing strategy. The high cardinality of labels in Claw, often auto-injected with verbose tags, becomes financially prohibitive. Our first step was a cardinality audit.

**Phase 1: Analysis and Label Design**
We instrumented a logging sidecar to analyze a week's worth of production traffic, categorizing log fields by their variability and query necessity.
* **High-Cardinality Detrimental:** `request_id`, `session_id`, `trace_id` (if used as a standalone label).
* **Medium-Cardinality Useful:** `kubernetes_namespace`, `kubernetes_pod_name`, `service_name`.
* **Low-Cardinality Ideal:** `environment` (prod/staging), `region`, `log_level` (error/warn/info), `app_component`.

The resulting Loki label schema was deliberately minimalist:
```yaml
# promtail/config.yaml snippet
scrape_configs:
- job_name: kubernetes-pods
kubernetes_sd_configs: [...]
relabel_configs:
- source_labels: [__meta_kubernetes_namespace_name]
target_label: namespace
- source_labels: [__meta_kubernetes_pod_name]
target_label: pod
- source_labels: [__meta_kubernetes_container_name]
target_label: container
- action: replace
source_labels: [__meta_kubernetes_namespace_name]
regex: (.*)
replacement: $1
target_label: job
# Static labels for low-cardinality filtering
- action: replace
target_label: environment
replacement: "prod-us-west2"
- action: replace
target_label: log_type
replacement: "application"
```
This ensures the index remains small and performant. All other fields remain within the log line itself, queryable via Loki's LogQL filters (`|= "request_id=abc123"`).

**Phase 2: Sampling Strategy Implementation**
Not all logs are of equal value. DEBUG-level logs from healthy endpoints are voluminous and rarely queried. We implemented selective sampling at the Promtail level, discarding a percentage of verbose, low-priority logs before they incurred any storage cost.
```yaml
# promtail/pipeline_stages.yaml
pipeline_stages:
- docker: {}
- regex:
expression: '.*level=(?Pw+).*'
- sampling:
rate: 1000 # Keep 1 in 1000 logs where...
drop_ratio: 0.9 # ...drop 90% of the rest.
source: level
values:
- debug
- info
# severity: error and warn are never sampled.
```
This stage alone reduced ingested volume by approximately 40%, as the majority of logs were at the INFO level. The sampling rate and criteria must be developed in consultation with the platform engineering and security teams to ensure audit trails are not compromised.

**Phase 3: Phased Migration & Performance Validation**
A dual-shipping strategy was employed for a two-week period, routing logs to both Claw and the new Loki cluster. This allowed for direct query result comparison and performance benchmarking. We established a suite of common operational and debugging queries and measured p99 latency in both systems. Key findings:
* Simple label-based queries (`{namespace="api", log_type="error"}`) were 15-20% faster in Loki due to the compact index.
* Complex full-text searches across 30-day windows in high-volume streams were slower in Loki by a factor of 1.5-2x, which was deemed acceptable given their infrequent use. This was mitigated by creating dedicated `tsdb` volumes for specific high-priority streams.
* Storage costs on S3, even with 30-day retention and 11-zone redundancy, were 92% lower than the equivalent ingestion cost in Claw.

The final cutover was performed namespace-by-namespace, monitoring Loki distributor and ingester resource utilization closely. The total cost of the managed Kubernetes nodes for the Loki cluster (distributors, ingesters, queriers, index gateways) plus S3 storage now sits at roughly 27% of the previous Claw bill. This case study demonstrates that for organizations with substantial log volume, the operational overhead of managing a Loki cluster is a financially justified engineering task, provided the initial analysis and label design are given rigorous attention.



   
Quote