Skip to content

Metrics System Architecture Diagrams

Version: 2.0
Last Updated: February 2, 2026


1. High-Level System Architecture

┌─────────────────────────────────────────────────────────────────────────┐
│                          eXate METRICS SYSTEM                            │
│                     Installation-Wide Billing Pipeline                   │
└─────────────────────────────────────────────────────────────────────────┘

┌──────────────┐      ┌──────────────┐      ┌──────────────┐
│  ds_micro_   │      │ com.exate.   │      │ com.exate.   │
│  APIgator    │◄────►│   core       │◄────►│ aggregator   │
│              │      │              │      │  (Insight)   │
└──────────────┘      └──────────────┘      └──────────────┘
│                     │                     │
│ • Collection        │ • Models            │ • Persistence
│ • Pre-Aggregation   │ • Configuration     │ • IBM Submission
│ • Leader Election   │ • Redis Cache       │ • Report Storage
│ • Reporting APIs    │ • Window Logic      │ 
│ • IBM Integration   │                     │
└─────────────────────┴─────────────────────┴──────────────┘

2. Request Flow Architecture

                          ┌──────────────┐
                          │ Client       │
                          │ Application  │
                          └───────┬──────┘
                                  │
                   POST /protect/mask (with data)
                                  │
                                  ▼
                    ┌─────────────────────────┐
                    │ MetricsCollection       │
                    │ Interceptor             │
                    │ • Captures metadata     │
                    │ • In-memory cache       │
                    │ • Per-tenant tracking   │
                    └───────────┬─────────────┘
                                │
                          60s flush timer
                                │
                                ▼
                    ┌─────────────────────────┐
                    │ Redis                   │
                    │ • Raw metrics per       │
                    │   tenant/window         │
                    │ • Key: {tenant}:        │
                    │   {window}:{metric}     │
                    └───────────┬─────────────┘
                                │
                    ┌───────────┴──────────────┐
                    │ Pre-Aggregation Service  │
                    │ (Hourly, Leader Only)    │
                    │                          │
                    │ • Read raw metrics       │
                    │ • Aggregate per tenant   │
                    │ • Assign UUID            │
                    │ • Store snapshot         │
                    └───────────┬──────────────┘
                                │
                                ▼
                    ┌─────────────────────────┐
                    │ Redis                   │
                    │ • Pre-computed snapshots│
                    │ • UUID → JSON           │
                    │ • Ready for reporting   │
                    └───────────┬─────────────┘
                                │
                  ┌─────────────┴─────────────┐
                  │                           │
                  ▼                           ▼
         ┌────────────────┐        ┌──────────────────┐
         │ Preview API    │        │ Report/Send APIs │
         │ (read-only)    │        │ (with persist)   │
         └────────────────┘        └─────────┬────────┘
                                              │
                                              ▼
                                   ┌──────────────────────┐
                                   │ Insight API          │
                                   │ (Batch Persistence)  │
                                   │                      │
                                   │ • UUID idempotency   │
                                   │ • DB storage         │
                                   │ • IBM submission     │
                                   └──────────────────────┘

3. Installation-Wide Reporting Flow

┌─────────────────────────────────────────────────────────────────────┐
│                    POST /api/metrics/send                            │
└─────────────────────────────────────────────────────────────────────┘
                                 │
                                 ▼
                    ┌────────────────────────┐
                    │ 1. Acquire Lock        │
                    │ TTL: 10 minutes        │
                    └────────┬───────────────┘
                             │
                     ┌───────┴───────┐
                     │ Lock Success? │
                     └───────┬───────┘
                             │
                    ┌────────┴────────┐
                    │ No              │ Yes
                    ▼                 ▼
            ┌─────────────┐   ┌──────────────────────┐
            │ Return 409  │   │ 2. Get Closed Windows│
            │ Conflict    │   │ (isClosed = true)    │
            └─────────────┘   └──────────┬───────────┘
                                         │
                                         ▼
                              ┌──────────────────────────┐
                              │ 3. Get All Tenants       │
                              │ (from closed windows)    │
                              └──────────┬───────────────┘
                                         │
                                         ▼
                              ┌──────────────────────────┐
                              │ 4. For Each Tenant:      │
                              │   • Get persisted UUIDs  │
                              │   • Get snapshots        │
                              │   • Filter unpersisted   │
                              └──────────┬───────────────┘
                                         │
                                ┌────────┴────────┐
                                │ Pending exists? │
                                └────────┬────────┘
                                         │
                                ┌────────┴────────┐
                                │ No              │ Yes
                                ▼                 ▼
                        ┌──────────────┐  ┌──────────────────┐
                        │ Return 204   │  │ 5. Batch Persist │
                        │ No Content   │  │ (Single HTTP)    │
                        └──────────────┘  └────────┬─────────┘
                                                   │
                                                   ▼
                                        ┌──────────────────────┐
                                        │ 6. Mark UUIDs as     │
                                        │    Persisted         │
                                        │ (Redis SET - PERM)   │
                                        └────────┬─────────────┘
                                                 │
                                                 ▼
                                        ┌──────────────────────┐
                                        │ 7. Update last_report│
                                        │ (per tenant)         │
                                        └────────┬─────────────┘
                                                 │
                                                 ▼
                                        ┌──────────────────────┐
                                        │ 8. Release Lock      │
                                        └────────┬─────────────┘
                                                 │
                                                 ▼
                                        ┌──────────────────────┐
                                        │ Return 200 OK        │
                                        │ with DB UUIDs        │
                                        └──────────────────────┘

4. UUID Idempotency Architecture

┌─────────────────────────────────────────────────────────────────────┐
│                     UUID LIFECYCLE                                   │
└─────────────────────────────────────────────────────────────────────┘

┌────────────────────┐
│ Pre-Aggregation    │ ──► UUID = UUID.randomUUID()
│ (Hourly)           │     "abc-123-def-456"
└─────────┬──────────┘
          │
          ▼
┌──────────────────────────────────────────────────┐
│ Redis: Pre-Computed Snapshot                     │
│ {                                                │
│   "uuid": "abc-123-def-456",                     │
│   "tenantId": 123,                               │
│   "windowId": "202601",                          │
│   "metrics": {...}                               │
│ }                                                │
└─────────┬────────────────────────────────────────┘
          │
          ▼
┌──────────────────────────────────────────────────┐
│ Send API - Idempotency Check                     │
│                                                  │
│ persistedUuids = Redis.SMEMBERS(                 │
│   "tenant:123:persisted"                         │
│ )                                                │
│                                                  │
│ IF "abc-123-def-456" IN persistedUuids:          │
│     SKIP (already sent)                          │
│ ELSE:                                            │
│     PERSIST to Insight API                       │
└─────────┬────────────────────────────────────────┘
          │
          ▼
┌──────────────────────────────────────────────────┐
│ Insight API Returns DB UUID                      │
│ "db-uuid-999-from-postgres"                      │
└─────────┬────────────────────────────────────────┘
          │
          ▼
┌──────────────────────────────────────────────────┐
│ Mark as Persisted                                │
│                                                  │
│ Redis.SADD(                                      │
│   "tenant:123:persisted",                        │
│   "abc-123-def-456"  <-- Original UUID           │
│ )                                                │
│                                                  │
│ ✅ NEVER CLEARED (Permanent Audit Trail)         │
└──────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────┐
│ Retry Scenario                                  │
│                                                 │
│ User calls /send again:                         │
│   1. Check: "abc-123-def-456" in persisted? ✅  │
│   2. Skip: Already sent                         │
│   3. Return: 0 reports generated                │
│                                                 │
│ ✅ NO DUPLICATE BILLING                         │
└─────────────────────────────────────────────────┘

5. Closed Window Logic

┌─────────────────────────────────────────────────────────────────────┐
│                    WINDOW LIFECYCLE                                  │
└─────────────────────────────────────────────────────────────────────┘

Granularity: MONTH

Timeline:
│
│  Jan 1                Jan 31            Feb 1              Feb 28
│  00:00:00            23:59:59          00:00:00           23:59:59
├─────────────────────────┼────────────────────────────────────┼
│ Window: 202601          │       Window: 202602               │
│ (January 2026)          │       (February 2026)              │
└─────────────────────────┴────────────────────────────────────┴

Current Time: Feb 15, 2026

Check Window Status:
┌──────────┬────────────┬─────────────┬────────────────────┐
│ Window   │ End Time   │ Now > End?  │ isClosed           │
├──────────┼────────────┼─────────────┼────────────────────┤
│ 202601   │ Jan 31 EOD │ ✅ Yes      │ ✅ true (INCLUDE)  │
│ 202602   │ Feb 28 EOD │ ❌ No       │ ❌ false (EXCLUDE) │
└──────────┴────────────┴─────────────┴────────────────────┘

Report Generation Result:
✅ January 2026 data INCLUDED (complete)
❌ February 2026 data EXCLUDED (in progress)

User sees:
{
  "reportsGenerated": 1,
  "reports": [
    { "windowId": "202601", ... }  // ✅ January only
  ]
}

6. IBM Integration Flow

┌─────────────────────────────────────────────────────────────────────┐
│                    IBM MODE SCHEDULER                                │
└─────────────────────────────────────────────────────────────────────┘

Cron: */15 * * * * (Every 15 minutes)

                    ┌──────────────────┐
                    │ Scheduler Fires  │
                    └────────┬─────────┘
                             │
                             ▼
                    ┌────────────────────┐
                    │ IS_IBM_MODE?       │
                    └────────┬───────────┘
                             │
                    ┌────────┴────────┐
                    │ No              │ Yes
                    ▼                 ▼
            ┌─────────────┐   ┌──────────────────────┐
            │ Skip        │   │ sendReports(         │
            └─────────────┘   │   submitToIbm=true   │
                              │ )                    │
                              └──────────┬───────────┘
                                         │
                           ┌─────────────┴─────────────┐
                           │                           │
                           ▼                           ▼
                ┌──────────────────┐        ┌──────────────────┐
                │ 1. Persist to    │        │ 2. Submit to IBM │
                │    Insight API   │        │    Metering API  │
                │    (batch)       │        │    (per-tenant)  │
                └────────┬─────────┘        └────────┬─────────┘
                         │                           │
                         └───────────┬───────────────┘
                                     │
                                     ▼
                          ┌──────────────────────┐
                          │ 3. Update IBM Status │
                          │ • SUBMITTED ✅       │
                          │ • FAILED ❌          │
                          └──────────┬───────────┘
                                     │
                                     ▼
                          ┌──────────────────────┐
                          │ 4. Auto Cleanup      │
                          │ clearReportedWindows()│
                          └──────────────────────┘

IBM API Payload per Tenant:
{
  "start": 1738368000000,
  "end": 1738368899999,
  "region": "us-south",
  "plan_id": "...",
  "measured_usage": [
    {
      "measure": "ATTRIBUTE_COUNT",
      "quantity": 450
    },
    ...
  ]
}

7. Redis Key Hierarchy

EX8:PROD:COMMON:USAGE_METRICS
│
├── {tenantId}:{windowId}:jobtype              [HASH] Raw metrics
├── {tenantId}:{windowId}:navigationtokens...  [HASH] Raw metrics
│
├── window:{windowId}:tenants                  [SET] Tenant IDs
├── window:{windowId}:granularity              [STRING] "MONTH"
│
├── snapshots:{windowId}                       [HASH] tenantId→JSON
├── precomputed                                [ZSET] windowId by time
├── active                                     [ZSET] windowId by time
│
├── tenant:{tenantId}:persisted                [SET] UUIDs (PERMANENT)
├── tenant:{tenantId}:last_report              [STRING] timestamp
│
├── installation:lock                          [STRING] "1" (TTL: 600s)
├── granularity                                [STRING] "MONTH"
└── leader                                     [STRING] "pod-abc-123"

8. Data Model Relationships

┌──────────────────────────────────────────────────────────────────┐
│                    MODEL RELATIONSHIPS                            │
└──────────────────────────────────────────────────────────────────┘

PreComputedSnapshot (Redis)          MetricsSnapshot (DB)
┌─────────────────────────┐          ┌──────────────────────┐
│ uuid: "abc-123"         │──────┐   │ uuid: "db-uuid-999"  │
│ tenantId: 123           │      │   │ tenantId: UUID(123)  │
│ windowId: "202601"      │      │   │ windowId: "202601"   │
│ metrics: Map[...]       │      │   │ totalManifests: 120  │
│ manifests: 120          │      │   │ totalAttributes: 450 │
│ attributes: 450         │      │   │ status: "PERSISTED"  │
│ ...                     │      │   │ ibmStatus: "SUBMITTED"│
└─────────────────────────┘      │   └──────────────────────┘
                                 │
                    toUsageMetrics()
                                 │
                                 ▼
                    ┌────────────────────────┐
                    │ UsageMetrics (Payload) │
                    │                        │
                    │ uuid: "abc-123"        │
                    │ tenantId: UUID(123)    │
                    │ windowId: "202601"     │
                    │ hostname: "pod-1"      │
                    │ environment: "PROD"    │
                    │ ...                    │
                    └────────────────────────┘

Persisted UUIDs (Redis SET)
┌──────────────────────────────┐
│ tenant:123:persisted         │
│ • "abc-123" ◄─────────────┐  │
│ • "def-456"               │  │
│ • "ghi-789"               │  │
│                           │  │
│ ✅ PERMANENT AUDIT TRAIL  │  │
│ ❌ NEVER CLEARED          │  │
└───────────────────────────┼──┘
                            │
                  Used for idempotency
                  check before persist

9. Service Dependencies

┌─────────────────────────────────────────────────────────────────────┐
│                    SERVICE ARCHITECTURE                              │
└─────────────────────────────────────────────────────────────────────┘

┌───────────────────────────────────────────────────────────────────┐
│                         ds_micro_APIgator                          │
├───────────────────────────────────────────────────────────────────┤
│                                                                   │
│  MetricsController                                                │
│      │                                                            │
│      ├──► MetricsPersistenceService                              │
│      │       │                                                    │
│      │       ├──► MetricsPreAggregationService                   │
│      │       │       └──► RedisCache                             │
│      │       │                                                    │
│      │       ├──► IBMMeteringClient                              │
│      │       │       └──► IBM Cloud Metering API                 │
│      │       │                                                    │
│      │       └──► RestTemplate (Insight API)                     │
│      │               │                                            │
│      │               └──► com.exate.aggregator/api/reports/log   │
│      │                                                            │
│      └──► MetricsLeaderElection                                  │
│              └──► RedisCache                                      │
│                                                                   │
└───────────────────────────────────────────────────────────────────┘

┌───────────────────────────────────────────────────────────────────┐
│                     com.exate.aggregator (Insight)                 │
├───────────────────────────────────────────────────────────────────┤
│                                                                   │
│  ReportController                                                 │
│      │                                                            │
│      └──► ReportService                                          │
│              │                                                    │
│              └──► MetricsService                                 │
│                      │                                            │
│                      ├──► getMetricsSnapshotByUUID() (idempotency)│
│                      └──► persistUsageMetrics() (DB insert)      │
│                                                                   │
└───────────────────────────────────────────────────────────────────┘

┌───────────────────────────────────────────────────────────────────┐
│                         com.exate.core                             │
├───────────────────────────────────────────────────────────────────┤
│                                                                   │
│  • Models (MetricsSnapshot, PreComputedSnapshot, etc.)            │
│  • Configuration (MetricsConfig)                                  │
│  • RedisCache (WindowedMetricsCache)                             │
│  • MetricsWindow (boundary calculations)                         │
│                                                                   │
└───────────────────────────────────────────────────────────────────┘

10. Error Handling Flow

┌─────────────────────────────────────────────────────────────────────┐
│                    ERROR HANDLING STRATEGY                           │
└─────────────────────────────────────────────────────────────────────┘

Send API Error Scenarios:

1. Lock Already Held
   ┌──────────────────┐
   │ Try Acquire Lock │
   └────────┬─────────┘
            │ Fail
            ▼
   ┌──────────────────┐
   │ HTTP 409 Conflict│
   │ "Operation in    │
   │  progress"       │
   └──────────────────┘

2. No Closed Windows
   ┌──────────────────┐
   │ Get Closed       │
   │ Windows          │
   └────────┬─────────┘
            │ Empty
            ▼
   ┌──────────────────┐
   │ HTTP 204 No      │
   │ Content          │
   └──────────────────┘

3. All UUIDs Already Persisted
   ┌──────────────────┐
   │ Filter Unpersisted│
   └────────┬─────────┘
            │ Empty
            ▼
   ┌──────────────────┐
   │ HTTP 204 No      │
   │ Content          │
   └──────────────────┘

4. Insight API Failure
   ┌──────────────────┐
   │ Call Insight API │
   └────────┬─────────┘
            │ HTTP 5xx
            ▼
   ┌──────────────────┐
   │ Release Lock     │
   │ Throw            │
   │ DownstreamService│
   │ Exception        │
   └────────┬─────────┘
            │
            ▼
   ┌──────────────────┐
   │ HTTP 500 Error   │
   │ UUIDs NOT marked │
   │ as persisted     │
   │ ✅ Safe to retry │
   └──────────────────┘

5. IBM Submission Failure
   ┌──────────────────┐
   │ Submit to IBM    │
   └────────┬─────────┘
            │ Fail
            ▼
   ┌──────────────────┐
   │ Update ibmStatus │
   │ = "FAILED"       │
   │                  │
   │ But DB persist   │
   │ succeeds ✅      │
   │                  │
   │ (Can retry IBM   │
   │  separately)     │
   └──────────────────┘

For complete documentation, see METRICS_SYSTEM.md