# Flexport Observability

> Set up observability for Flexport logistics integrations with metrics, structured logging, distributed tracing, and alerting dashboards. Trigger: "flexport monitoring", "flexport observability", "flexport metrics", "flexport alerts".

- Skill: `gabrielmoreira/flexport-observability` (Agent Skill)
- Install (CLI): `npx skillmds@latest add gabrielmoreira/flexport-observability`
- Raw SKILL.md: https://api.skillmd.com/api/skills/gabrielmoreira/flexport-observability/raw
- Safety review: pending (external: skill-scanner PASS, skillspector PASS)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- License: MIT
- Author: gabrielmoreira (https://skillmd.com/u/gabrielmoreira)
- Updated: 2026-09-09
- Page: https://skillmd.com/skills/gabrielmoreira/flexport-observability

---

# Flexport Observability

## Overview

Full observability stack for Flexport integrations: Prometheus metrics for API health, pino structured logging for debugging, OpenTelemetry tracing for latency analysis, and Grafana dashboards for monitoring.

## Prerequisites

- An approved telemetry schema using aggregate measurements and opaque correlation IDs.
- Named alert owners, escalation thresholds, secure dashboard access, retention rules, and synthetic alert fixtures.

## Output

Publish an observability receipt with metric definitions, dashboard/alert references, threshold tests, owner, and review date. Metrics, traces, and logs must exclude shipment payloads, addresses, invoices, documents, and credentials.

## Error Handling

- Reject telemetry fields that contain sensitive logistics data or headers.
- Alert on unexpected destination, queue, access, or integrity anomalies and route them to the incident owner.
- Suppress noise only through a documented time-bound rule that preserves incident visibility.

## Examples

Send one successful and one rejected fictional event. Confirm dashboards report only aggregate outcomes and opaque IDs, an alert fires at the agreed threshold, and no payload or secret appears in the alert message.

## Instructions

### Step 1: Prometheus Metrics

```typescript
import { Counter, Histogram, Gauge, register } from 'prom-client';

const flexportRequests = new Counter({
  name: 'flexport_api_requests_total',
  help: 'Total Flexport API requests',
  labelNames: ['method', 'endpoint', 'status'],
});

const flexportLatency = new Histogram({
  name: 'flexport_api_latency_seconds',
  help: 'Flexport API response time',
  labelNames: ['endpoint'],
  buckets: [0.1, 0.25, 0.5, 1, 2.5, 5, 10],
});

const flexportRateLimit = new Gauge({
  name: 'flexport_rate_limit_remaining',
  help: 'Remaining API calls in current window',
});

// Instrumented fetch wrapper
async function instrumentedFlexport(path: string, options: RequestInit = {}) {
  const endpoint = path.split('?')[0];
  const timer = flexportLatency.startTimer({ endpoint });
  try {
    const res = await fetch(`https://api.flexport.com${path}`, { ...options, headers: { ...headers, ...options.headers } });
    flexportRequests.inc({ method: options.method || 'GET', endpoint, status: res.status.toString() });
    const remaining = res.headers.get('X-RateLimit-Remaining');
    if (remaining) flexportRateLimit.set(parseInt(remaining));
    timer();
    return res;
  } catch (err) {
    flexportRequests.inc({ method: options.method || 'GET', endpoint, status: 'error' });
    timer();
    throw err;
  }
}
```

### Step 2: Structured Logging

```typescript
import pino from 'pino';

const logger = pino({
  name: 'flexport-integration',
  level: process.env.LOG_LEVEL || 'info',
  redact: ['headers.Authorization', 'apiKey'],
});

// Log every API call with context
async function loggedFlexport(path: string, options: RequestInit = {}) {
  const start = Date.now();
  const res = await instrumentedFlexport(path, options);
  logger.info({
    service: 'flexport',
    path,
    method: options.method || 'GET',
    status: res.status,
    latencyMs: Date.now() - start,
    rateRemaining: res.headers.get('X-RateLimit-Remaining'),
  }, 'Flexport API call');
  return res;
}
```

### Step 3: Alert Rules

```yaml
# prometheus-alerts.yml
groups:
  - name: flexport
    rules:
      - alert: FlexportAPIErrors
        expr: rate(flexport_api_requests_total{status=~"5.."}[5m]) > 0.1
        for: 5m
        labels: { severity: critical }
        annotations:
          summary: "Flexport API error rate elevated"

      - alert: FlexportRateLimitLow
        expr: flexport_rate_limit_remaining < 10
        for: 1m
        labels: { severity: warning }
        annotations:
          summary: "Flexport rate limit nearly exhausted"

      - alert: FlexportHighLatency
        expr: histogram_quantile(0.99, flexport_api_latency_seconds_bucket) > 5
        for: 5m
        labels: { severity: warning }
```

### Grafana Dashboard Panels

| Panel | Query | Purpose |
|-------|-------|---------|
| Request rate | `rate(flexport_api_requests_total[5m])` | Throughput |
| Error rate | `rate(flexport_api_requests_total{status=~"4..\|5.."}[5m])` | Reliability |
| p99 latency | `histogram_quantile(0.99, rate(flexport_api_latency_seconds_bucket[5m]))` | Performance |
| Rate limit headroom | `flexport_rate_limit_remaining` | Quota |

## Resources

- [prom-client](https://github.com/siimon/prom-client)
- [pino](https://github.com/pinojs/pino)
- [Flexport Status](https://status.flexport.com)

## Next Steps

For incident response, see `flexport-incident-runbook`.

