Skip to content

Web Service Monitoring — Complete Guide to Observability

DodaTech Updated 2026-06-28 4 min read

In this tutorial, you will learn about Web Service Monitoring. We cover key concepts, practical examples, and best practices to help you master this topic.

Web service monitoring tracks availability, response time, error rates, and throughput using health checks, metrics collection, structured logging, and alerting to ensure reliable operation of SOAP and REST services.

What You'll Learn

  • Key metrics for monitoring web services
  • Implementing health checks and liveness probes
  • Structured logging and centralized log aggregation

Why It Matters

Users detect outages before operations teams if monitoring is not in place. Proactive monitoring alerts teams to issues before they impact users, reducing downtime and mean time to recovery.

Real-World Use

Durga Antivirus Pro monitors all 50+ web service endpoints with Prometheus metrics, structured JSON logging to Elasticsearch, and Grafana dashboards that show real-time latency percentiles and error rates.

flowchart LR
    S["Service"] --> M["Metrics (Prometheus)"]
    S --> L["Logs (Elasticsearch)"]
    S --> H["Health Checks"]
    M --> G["Grafana Dashboard"]
    L --> K["Kibana"]
    H --> A["Alert Manager"]
    A --> N["Notification (PagerDuty)"]
    style M fill:#dbeafe,stroke:#2563eb

Code Examples

from prometheus_client import Counter, Histogram, start_http_server
from flask import Flask, request, jsonify
import time

REQUEST_COUNT = Counter('ws_requests_total', 'Total requests', ['method', 'endpoint', 'status'])
REQUEST_LATENCY = Histogram('ws_request_duration_seconds', 'Request latency', ['method', 'endpoint'])

app = Flask(__name__)

@app.route('/api/threats')
def get_threats():
    start = time.time()
    try:
        threats = query_threats()
        REQUEST_COUNT.labels(method='GET', endpoint='/threats', status='200').inc()
        return jsonify(threats)
    except Exception as e:
        REQUEST_COUNT.labels(method='GET', endpoint='/threats', status='500').inc()
        return jsonify({'error': str(e)}), 500
    finally:
        duration = time.time() - start
        REQUEST_LATENCY.labels(method='GET', endpoint='/threats').observe(duration)

start_http_server(8000)
app.run(port=5000)

Expected output: Prometheus metrics exposed at /metrics for scraping and dashboard visualization.

// Structured JSON logging
const winston = require('winston');

const logger = winston.createLogger({
  level: 'info',
  format: winston.format.json(),
  defaultMeta: { service: 'threat-service' },
  transports: [
    new winston.transports.Console(),
    new winston.transports.File({ filename: 'logs/error.log', level: 'error' }),
  ],
});

app.get('/api/threats', (req, res) => {
  const start = Date.now();
  queryThreats()
    .then(threats => {
      logger.info('Threats queried', {
        count: threats.length,
        duration: Date.now() - start,
        requestId: req.headers['x-request-id'],
      });
      res.json(threats);
    })
    .catch(err => {
      logger.error('Threat query failed', {
        error: err.message,
        duration: Date.now() - start,
      });
      res.status(500).json({ error: 'Internal error' });
    });
});

Expected output: Structured JSON logs with consistent fields for easy parsing and aggregation in Elasticsearch.

# Health check endpoint with dependency status
from flask import Flask, jsonify
import redis, requests

app = Flask(__name__)

@app.route('/health')
def health_check():
    status = {'service': 'threat-api', 'healthy': True, 'dependencies': {}}

    try:
        r = redis.Redis()
        r.ping()
        status['dependencies']['redis'] = 'up'
    except Exception as e:
        status['dependencies']['redis'] = f'down: {e}'
        status['healthy'] = False

    try:
        resp = requests.get('http://internal-db:5432/health', timeout=2)
        status['dependencies']['database'] = 'up' if resp.ok else 'down'
    except Exception as e:
        status['dependencies']['database'] = f'down: {e}'
        status['healthy'] = False

    return jsonify(status), 200 if status['healthy'] else 503

Expected output: Health endpoint returns 200 with all dependencies up or 503 with degraded status.

Common Mistakes

1. No Automated Alerts

Collecting metrics without alerting means no one knows when thresholds are exceeded. Define alert rules for every key metric.

2. Monitoring Only Happy Path

A service that returns 200 may be returning stale data or silently failing. Monitor response correctness.

3. No Log Correlation

Without request IDs, correlating logs across services is nearly impossible. Include trace/request IDs in every log entry.

4. Ignoring Percentiles

Average latency hides slow requests. Track p50, p95, and p99 latency to see the real user experience.

5. No Synthetic Monitoring

Real-user monitoring only catches issues after users are affected. Synthetic probes detect problems proactively.

Practice Questions

  1. What are four key metrics for web service monitoring?
  2. Why is structured logging better than plain text logging?
  3. What is the difference between p50, p95, and p99 latency?
  4. Why should health checks verify dependencies?
  5. How does synthetic monitoring differ from real-user monitoring?

Answers:

  1. Availability (uptime), latency (p50/p95/p99), error rate, and throughput (RPS).
  2. Structured logs are machine-parseable, enabling automated analysis and correlation across services.
  3. p50 is median latency, p95 is latency below which 95% of requests fall, p99 is latency below which 99% fall.
  4. A service may be running but dependent services (database, Redis) may be down, making it effectively unavailable.
  5. Synthetic monitoring uses simulated requests to proactively detect issues; real-user monitoring observes actual user traffic.

Challenge: Set up a monitoring stack for a SOAP-based weather service: implement health checks with dependency verification, expose Prometheus metrics (request count, latency histogram, error count), and create a Grafana dashboard with p50/p95/p99 latency panels.

FAQ

What is the difference between monitoring and observability?

: Monitoring tracks known metrics against thresholds; observability enables exploring unknown failure modes through logs, metrics, and traces.

What tools are commonly used for web service monitoring?

: Prometheus (metrics), Grafana (dashboards), ELK Stack (logs), Jaeger (tracing), and PagerDuty (alerting).

How often should health checks run?

: Every 10-30 seconds for critical services, every 5 minutes for non-critical ones.

What is a good alert threshold for error rate?

: Alert when error rate exceeds 1% over 5 minutes for critical services, 5% for non-critical.

How do you monitor SOAP web services?

: Same metrics apply (latency, errors, throughput) plus XML validation monitoring for schema Compliance.

Mini Project

Implement full observability for a web service: Prometheus metrics (counter, histogram, gauge), structured JSON logging with request IDs, a /health endpoint with dependency checks, and an alert rule that fires when p95 latency exceeds 500ms for 5 minutes.

What's Next

Learn about Web service security monitoring for detecting attacks, or explore Web service testing for preventing issues before they reach production.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro