MA

maintainx-observability

Adds metrics, structured logging, and alerting specifically for MaintainX API integrations.

Install

mkdir -p .claude/skills/maintainx-observability && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/7946" && unzip -o skill.zip -d .claude/skills/maintainx-observability && rm skill.zip

Installs to .claude/skills/maintainx-observability

Activation

This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.

Implement comprehensive observability for MaintainX integrations.
65 charsno explicit “when” trigger
Intermediate

Key capabilities

  • Record API request counts and status codes
  • Measure API latency using histograms
  • Track rate limit hits and synchronization lag
  • Expose metrics via a Prometheus scrape endpoint
  • Log operations as structured JSON entries

How it works

It uses an instrumented Axios client to intercept requests and responses, recording metrics and logging activity, while providing an Express server to expose these metrics for scraping.

Inputs & outputs

You give it
API request lifecycle events
You get back
Prometheus-compatible metrics and structured JSON logs

When to use maintainx-observability

  • Set up Prometheus metrics
  • Monitor API latency
  • Configure rate limit alerts
  • Log API activity

About this skill

MaintainX Observability

Overview

Implement metrics, structured logging, and alerting for MaintainX integrations to ensure reliability and rapid issue detection.

Prerequisites

  • MaintainX integration deployed
  • Node.js 18+
  • Monitoring platform (Prometheus/Grafana, Datadog, or CloudWatch)

Instructions

Step 1: Prometheus Metrics

// src/observability/metrics.ts
import { Counter, Histogram, Gauge, Registry } from 'prom-client';

const register = new Registry();

export const metrics = {
  apiRequests: new Counter({
    name: 'maintainx_api_requests_total',
    help: 'Total MaintainX API requests',
    labelNames: ['method', 'endpoint', 'status'],
    registers: [register],
  }),

  apiLatency: new Histogram({
    name: 'maintainx_api_latency_seconds',
    help: 'MaintainX API request latency',
    labelNames: ['method', 'endpoint'],
    buckets: [0.1, 0.25, 0.5, 1, 2.5, 5, 10],
    registers: [register],
  }),

  rateLimitHits: new Counter({
    name: 'maintainx_rate_limit_hits_total',
    help: 'Times rate limited by MaintainX API',
    registers: [register],
  }),

  workOrdersProcessed: new Counter({
    name: 'maintainx_work_orders_processed_total',
    help: 'Work orders processed',
    labelNames: ['action', 'status'],
    registers: [register],
  }),

  syncLag: new Gauge({
    name: 'maintainx_sync_lag_seconds',
    help: 'Seconds since last successful sync',
    registers: [register],
  }),
};

export { register };

Step 2: Instrumented API Client

// src/observability/instrumented-client.ts
import axios, { AxiosInstance } from 'axios';
import { metrics } from './metrics';

export function createInstrumentedClient(apiKey: string): AxiosInstance {
  const client = axios.create({
    baseURL: 'https://api.getmaintainx.com/v1',
    headers: { Authorization: `Bearer ${apiKey}`, 'Content-Type': 'application/json' },
    timeout: 30_000,
  });

  client.interceptors.request.use((config) => {
    (config as any).__startTime = process.hrtime.bigint();
    return config;
  });

  client.interceptors.response.use(
    (response) => {
      const elapsed = Number(process.hrtime.bigint() - (response.config as any).__startTime) / 1e9;
      const endpoint = response.config.url?.split('?')[0] || 'unknown';

      metrics.apiRequests.inc({
        method: response.config.method?.toUpperCase() || 'GET',
        endpoint,
        status: String(response.status),
      });
      metrics.apiLatency.observe(
        { method: response.config.method?.toUpperCase() || 'GET', endpoint },
        elapsed,
      );
      return response;
    },
    (error) => {
      const status = error.response?.status || 0;
      const endpoint = error.config?.url?.split('?')[0] || 'unknown';

      metrics.apiRequests.inc({
        method: error.config?.method?.toUpperCase() || 'GET',
        endpoint,
        status: String(status),
      });

      if (status === 429) {
        metrics.rateLimitHits.inc();
      }
      throw error;
    },
  );

  return client;
}

Step 3: Structured Logging

// src/observability/logger.ts

type LogLevel = 'debug' | 'info' | 'warn' | 'error';

interface LogEntry {
  level: LogLevel;
  message: string;
  service: string;
  timestamp: string;
  [key: string]: any;
}

class StructuredLogger {
  private service: string;

  constructor(service: string) {
    this.service = service;
  }

  private log(level: LogLevel, message: string, data?: Record<string, any>) {
    const entry: LogEntry = {
      level,
      message,
      service: this.service,
      timestamp: new Date().toISOString(),
      ...data,
    };
    // JSON output for log aggregation (ELK, CloudWatch, Datadog)
    console.log(JSON.stringify(entry));
  }

  info(message: string, data?: Record<string, any>) { this.log('info', message, data); }
  warn(message: string, data?: Record<string, any>) { this.log('warn', message, data); }
  error(message: string, data?: Record<string, any>) { this.log('error', message, data); }
  debug(message: string, data?: Record<string, any>) { this.log('debug', message, data); }
}

export const logger = new StructuredLogger('maintainx-integration');

// Usage
logger.info('Work order created', { workOrderId: 12345, priority: 'HIGH' });
logger.error('API call failed', { endpoint: '/workorders', status: 500, retryCount: 2 });

Step 4: Health and Metrics Endpoints

// src/observability/server.ts
import express from 'express';
import { register, metrics } from './metrics';

const app = express();

// Prometheus scrape endpoint
app.get('/metrics', async (req, res) => {
  res.set('Content-Type', register.contentType);
  res.end(await register.metrics());
});

// Health check with metrics
app.get('/health', async (req, res) => {
  const health = {
    status: 'healthy',
    uptime: process.uptime(),
    metrics: {
      totalRequests: await metrics.apiRequests.get(),
      rateLimitHits: await metrics.rateLimitHits.get(),
      syncLagSeconds: (await metrics.syncLag.get()).values[0]?.value || 0,
    },
  };
  res.json(health);
});

app.listen(9090, () => logger.info('Metrics server on :9090'));

Step 5: Alerting Rules (Prometheus)

# prometheus/alerts.yml
groups:
  - name: maintainx
    rules:
      - alert: MaintainXHighErrorRate
        expr: rate(maintainx_api_requests_total{status=~"5.."}[5m]) > 0.1
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "MaintainX API error rate > 10%"

      - alert: MaintainXHighLatency
        expr: histogram_quantile(0.95, rate(maintainx_api_latency_seconds_bucket[5m])) > 5
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "MaintainX API p95 latency > 5s"

      - alert: MaintainXRateLimited
        expr: rate(maintainx_rate_limit_hits_total[5m]) > 0
        for: 1m
        labels:
          severity: warning
        annotations:
          summary: "MaintainX API rate limiting detected"

      - alert: MaintainXSyncStale
        expr: maintainx_sync_lag_seconds > 900
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "MaintainX sync lag > 15 minutes"

Output

  • Prometheus metrics (request count, latency histogram, rate limit counter, sync lag gauge)
  • Instrumented axios client automatically recording metrics on every API call
  • Structured JSON logging for all operations
  • /metrics endpoint for Prometheus scraping
  • Alerting rules for error rate, latency, rate limits, and sync staleness

Error Handling

IssueCauseSolution
Metrics endpoint 500prom-client not initializedEnsure Registry is created before metrics
Missing labelsMetric name mismatchCheck labelNames match inc()/observe() calls
Log volume too highDebug logging in productionSet LOG_LEVEL=info in production
Stale sync alertSync job stoppedCheck cron schedule, restart sync process

Resources

Next Steps

For incident response, see maintainx-incident-runbook.

Examples

Datadog integration using DogStatsD:

import StatsD from 'hot-shots';

const dogstatsd = new StatsD({ prefix: 'maintainx.' });

// Record API call
dogstatsd.increment('api.requests', 1, { endpoint: '/workorders', status: '200' });
dogstatsd.histogram('api.latency', 0.45, { endpoint: '/workorders' });

When not to use it

  • When the integration is a simple script without long-running processes
  • When the environment lacks a monitoring platform like Prometheus or Datadog

Prerequisites

MaintainX integration deployedNode.js 18+Monitoring platform

Limitations

  • Metrics endpoint requires prom-client initialization
  • Debug logging can create excessive log volume in production
  • Sync lag alerts depend on the sync job schedule

How it compares

This method provides automated, standardized observability for every API call, rather than relying on manual, ad-hoc logging or console statements.

Compared to similar skills

maintainx-observability side by side with the closest alternatives in the catalog.

SkillInstallsUpdatedSafetyDifficulty
maintainx-observability (this skill)027dReviewIntermediate
sentry-install-auth027dReviewBeginner
perplexity-observability127dNo flagsIntermediate
documenso-observability027dReviewIntermediate

Try saying

Example prompts that trigger this skill in your AI assistant.

More by jeremylongshore

View all by jeremylongshore

analyzing-logs

jeremylongshore

Analyze application logs to detect performance issues, identify error patterns, and improve stability by extracting key insights.

14123

ollama-setup

jeremylongshore

Configure auto-configure Ollama when user needs local LLM deployment, free AI alternatives, or wants to eliminate hosted API costs. Trigger phrases: "install ollama", "local AI", "free LLM", "self-hosted AI", "replace OpenAI", "no API costs". Use when appropriate context detected. Trigger with relevant phrases based on skill purpose.

1167

backtesting-trading-strategies

jeremylongshore

Backtest crypto and traditional trading strategies against historical data. Calculates performance metrics (Sharpe, Sortino, max drawdown), generates equity curves, and optimizes strategy parameters. Use when user wants to test a trading strategy, validate signals, or compare approaches. Trigger with phrases like "backtest strategy", "test trading strategy", "historical performance", "simulate trades", "optimize parameters", or "validate signals".

1071

generating-database-seed-data

jeremylongshore

Process this skill enables AI assistant to generate realistic test data and database seed scripts for development and testing environments. it uses faker libraries to create realistic data, maintains relational integrity, and allows configurable data volumes. u... Use when working with databases or data models. Trigger with phrases like 'database', 'query', or 'schema'.

1033

cursor-codebase-indexing

jeremylongshore

Execute set up and optimize Cursor codebase indexing. Triggers on "cursor index setup", "codebase indexing", "index codebase", "cursor semantic search". Use when working with cursor codebase indexing functionality. Trigger with phrases like "cursor codebase indexing", "cursor indexing", "cursor".

885

testing-mobile-apps

jeremylongshore

Execute mobile app testing on iOS and Android devices/simulators. Use when performing specialized testing. Trigger with phrases like "test mobile app", "run iOS tests", or "validate Android functionality".

810

You might also like

sentry-install-auth

jeremylongshore

Install and configure Sentry SDK authentication. Use when setting up a new Sentry integration, configuring DSN, or initializing Sentry in your project. Trigger with phrases like "install sentry", "setup sentry", "sentry auth", "configure sentry DSN".

05

perplexity-observability

jeremylongshore

Set up comprehensive observability for Perplexity integrations with metrics, traces, and alerts. Use when implementing monitoring for Perplexity operations, setting up dashboards, or configuring alerting for Perplexity integration health. Trigger with phrases like "perplexity monitoring", "perplexity metrics", "perplexity observability", "monitor perplexity", "perplexity alerts", "perplexity tracing".

10

documenso-observability

jeremylongshore

Implement monitoring, logging, and tracing for Documenso integrations. Use when setting up observability, implementing metrics collection, or debugging production issues. Trigger with phrases like "documenso monitoring", "documenso metrics", "documenso logging", "documenso tracing", "documenso observability".

00

observe-whatsapp

engryamato

Observe and troubleshoot WhatsApp in Kapso: debug message delivery, inspect webhook deliveries/retries, triage API errors, and run health checks. Use when investigating production issues, message failures, or webhook delivery problems.

00

test-rest-health

deadl1f7

Test REST endpoint health. Use when: verifying REST API availability, debugging REST connection issues, checking gRPC client status via REST, validating proto catalogue via REST API.

00

setup-sap-btp-logging

leotrinh

Automates the setup of sap-btp-cloud-logging-client in a project.

00

Search skills

Search the agent skills registry