Skip to main content

grass-metrics

Unified metrics library for Grass projects. Supports DataDog (DogStatsD/UDP) and OpenTelemetry/OpenObserve (OTLP gRPC/HTTP) with automatic backend selection and dual-write mode.

Installation

# Core (no backend dependencies -- bring your own)
pip install grass-metrics

# With DataDog support
pip install "grass-metrics[datadog]"

# With OpenTelemetry support
pip install "grass-metrics[otel]"

# Both backends
pip install "grass-metrics[all]"

Quick Start

from grass_metrics import create_metrics_manager

metrics = create_metrics_manager()

metrics.increment("wl.my_service.items.processed")
metrics.gauge("wl.my_service.queue.size", 42)
metrics.histogram("wl.my_service.latency_seconds", 1.23)

# With extra tags
metrics.increment("wl.my_service.uploads.success", extra_tags=["provider:s3"])

# Shutdown (flushes OTel buffers)
metrics.shutdown()

Backend Selection

The factory picks the backend in this priority order:

Priority Source Example
1 backend argument to create_metrics_manager() create_metrics_manager("otel")
2 METRICS_BACKEND env var METRICS_BACKEND=dual
3 Local Redis key metrics_backend Set by preloader from cluster config
4 Default "datadog"

Supported values: datadog, otel, dual

  • datadog -- Sends metrics via DogStatsD UDP to the DataDog Agent
  • otel -- Sends metrics via OTLP (gRPC or HTTP) to an OpenTelemetry Collector / OpenObserve
  • dual -- Sends to both simultaneously (DataDog primary, OTel secondary). Useful during migration.

Environment Variables

Common

Variable Description Default
METRICS_BACKEND Backend selection datadog
ENVIRONMENT Environment name for tags unknown
CLUSTER_NAME or CLUSTERNAME Cluster name for tags unknown
HOSTNAME Host name for tags unknown
SERVICE_NAME Service name for tags -
POD_NAME Pod name for tags (optional) -
LOCAL_REDIS_DB_URI Redis URI for dynamic backend override -

DataDog

Variable Description Default
DD_AGENT_HOST DataDog agent host 172.17.0.1
DD_DOGSTATSD_PORT DogStatsD port 8125

OpenTelemetry / OpenObserve

Variable Description Default
OTEL_EXPORTER_ENDPOINT OTLP endpoint auto (see below)
OTEL_EXPORTER_AUTH_TOKEN Auth header value -
NODE_IP K8s node IP for local agent -

OTel endpoint resolution: explicit > OTEL_EXPORTER_ENDPOINT > http://{NODE_IP}:4317 > gateway fallback.

Kubernetes Pod Spec

env:
  - name: METRICS_BACKEND
    valueFrom:
      configMapKeyRef:
        name: scraper-config
        key: metrics_backend
  # DataDog
  - name: DD_AGENT_HOST
    valueFrom:
      fieldRef:
        fieldPath: status.hostIP
  # OTel
  - name: NODE_IP
    valueFrom:
      fieldRef:
        fieldPath: status.hostIP

Docker Compose

environment:
  METRICS_BACKEND: "otel"
  DD_AGENT_HOST: "datadog"          # service name
  OTEL_EXPORTER_ENDPOINT: "http://otel-collector:4317"

Domain-Specific Metrics (Consumer Pattern)

For projects with many metrics, wrap MetricsManager in a thin domain class:

from grass_metrics import create_metrics_manager

class YtdMetrics:
    DOWNLOADS_SUCCESS = "wl.ytd.downloads.healthy_count"
    DOWNLOADS_FAILED  = "wl.ytd.downloads.failed_count"
    UPLOAD_DURATION   = "wl.ytd.upload.duration_seconds"

    def __init__(self):
        self._m = create_metrics_manager()

    def increment_downloaded_videos_count(self):
        self._m.increment(self.DOWNLOADS_SUCCESS)

    def increment_failed_downloads_count(self):
        self._m.increment(self.DOWNLOADS_FAILED)

    def send_upload_duration(self, seconds: float):
        self._m.histogram(self.UPLOAD_DURATION, seconds)

    def shutdown(self):
        self._m.shutdown()

Direct Publisher Access

For advanced use cases, publishers can be used directly:

from grass_metrics import DatadogPublisher, OtelPublisher

dd = DatadogPublisher(statsd_host="172.17.0.1", statsd_port=8125)
dd.increment_count("my.counter", 1, ["env:prod"])

otel = OtelPublisher(service_name="my-svc", use_grpc=True)
otel.increment_count("my.counter", 1, ["env:prod"])
otel.shutdown()

Architecture

┌──────────────────────────────────────────────────┐
│                Consumer Project                   │
│  (e.g. YtdMetrics with domain-specific methods)  │
└──────────────────────┬───────────────────────────┘
                       │
         create_metrics_manager(backend=...)
                       │
                ┌──────▼──────┐
                │   Factory    │  resolves backend from
                │  factory.py  │  env / Redis / default
                └──────┬──────┘
                       │
          ┌────────────┼────────────┐
          │            │            │
    ┌─────▼─────┐ ┌───▼────┐ ┌────▼─────┐
    │ MetricsMgr│ │MetrMgr │ │ DualMgr  │
    │ + DD Pub  │ │+ OTel  │ │ DD + OTel│
    └───────────┘ └────────┘ └──────────┘

Metadata

Release files for grass-metrics 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for grass-metrics 0.2.0
File Size Uploaded
grass_metrics-0.2.0.tar.gz 13.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for grass-metrics 0.2.0
File Interpreter ABI Platform
grass_metrics-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 26.8 kB

Release files / grass_metrics-0.2.0.tar.gz

Download URL grass_metrics-0.2.0.tar.gz
Size 13.0 kB
Tags Source
SHA-256 checksum
How to use checksums
975f306485e7d598e36d94fa7b65ce4f19e16a1f5e5fe8b4dadc5a388083a368
BLAKE2b-256 checksum
How to use checksums
dd141f833be498105c3568c930171e7987dfd1e7af2c3e3fda462455b6177726
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.3

Release files / grass_metrics-0.2.0-py3-none-any.whl

Download URL grass_metrics-0.2.0-py3-none-any.whl
Size 13.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
673d52c90220b59231b7c48c82933585beae9ce963bff9a17f91b62a51bb73fa
BLAKE2b-256 checksum
How to use checksums
e4ce74e7d564815ca8e42983a6e474ec79680ccc1ba0ad4daf8f98195821810d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.3

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page