API Monitoring and Logging
By the Syncfusion DevTutorials team · Last updated
Use structured logs, correlation ids, health checks and RED metrics to see what your API is doing and find bugs fast.
API monitoring and logging means collecting information about what your API is doing, so that you can find problems, understand failures, and keep the system healthy.
If users report errors, slow responses, or missing data, monitoring and logging help you discover what happened and why. Without visibility into your API, diagnosing problems becomes difficult. Good monitoring helps you detect issues early, often before customers notice them.
Watch a Bug Hide in the Logs
Customers report that some orders fail, while others work normally. Press Run.
Program.cs — string logs
Results:
- The first order succeeds with
201 Created. - The second order fails with
500 Internal Server Error. - The logs show:
Order received,Order received,Something failed
The problem is that these logs do not answer important questions. Which request failed? Which customer submitted it? Which application version sent it? What caused the failure? The logs record that something happened, but not enough information to investigate it.
In simple words: logs are only useful if they contain enough information to explain what happened.
In these examples, log entries are stored in memory and shown through GET /debug/logs. Real applications send logs to central systems such as Seq, Elasticsearch, Azure Monitor, or Application Insights. Never expose a /debug/logs endpoint in production.
TL;DR
- Logs record individual events.
- Metrics show numbers over time.
- Health checks indicate whether the API can currently serve requests.
- Use structured logs with named fields.
- Give every request a correlation id.
- Return the correlation id in the response.
- Create liveness and readiness health checks.
- Monitor the rate, the errors, and the duration (RED metrics).
- Monitor p95 latency, not only averages.
- Never log passwords, tokens, API keys, or full card numbers.
A Real-World Example
Think about an aircraft flight recorder. It does not record messages such as "The flight was fine." Instead, it records specific values, such as the speed, the altitude, the engine temperature, and the positions of the switches. Investigators can rebuild exactly what happened.
Good API monitoring works the same way. Instead of recording vague messages, it records facts that can be searched, filtered, and analyzed.
Structured logs store searchable fields instead of unstructured text.
What You Will Learn
In this lesson, you will learn:
- Why plain text logs are often insufficient.
- How structured logging improves troubleshooting.
- How correlation ids track requests across systems.
- How health checks work.
- How RED metrics measure API performance.
- How monitoring helps identify root causes quickly.
Structured Logs
A structured log stores properties with names instead of writing plain sentences.
Example: {"level": "Error", "event": "OrderFailed", "path": "/orders", "status": 500, "appVersion": "2.3", "error": "quantity is not a number"}
Each property can be searched and filtered.
Program.cs — structured logs
When you review the logs, you see that the successful orders come from app version 2.4, and the failed orders come from app version 2.3. The error message is: quantity is not a number
The root cause becomes obvious. The older application version is submitting invalid data.
Because the information is stored as fields, you can easily filter with level = Error and see only the failures.
Use the same field names everywhere in the application. For example, appVersion should always be called appVersion, not sometimes appVer or version. Consistent names make searching and reporting much easier.
Structured Logging in ASP.NET Core
Real ASP.NET Core applications commonly use ILogger.
Example:
logger.LogError(
"Order failed for app {AppVersion}: {Error}",
"2.3",
"quantity is not a number");
The values inside braces become structured fields that can be queried later.
Never log passwords, access tokens, API keys, refresh tokens, or full credit card numbers. If card information is needed, log only the last four digits.
Follow a Request with Correlation IDs
A single request often creates multiple log entries. For example: OrderReceived, ValidatePayment, PaymentCharged, OrderCompleted
Without a shared identifier, it is difficult to tell which entries belong together. A correlation id solves this problem.
Middleware performs the following steps:
- Reads
X-Correlation-Idif provided. - Generates one if missing.
- Adds it to every log entry.
- Returns it in the response.
Program.cs — correlation id
Example: the client request has the header X-Correlation-Id: app-7f3a91, and the response has the header X-Correlation-Id: app-7f3a91.
If no value is provided, a value such as X-Correlation-Id: req-0001 is generated automatically.
Now every log entry contains the same identifier. Searching for req-0001 shows the complete story of that request.
A common industry standard is W3C Trace Context. It uses a traceparent header, so that tracing information can flow between services. OpenTelemetry builds on this standard and collects logs, metrics, and traces across distributed systems.
Health Checks
A health check endpoint reports whether the API is currently healthy. Load balancers, containers, and orchestration systems use these endpoints to decide whether traffic should be sent to the service.
Liveness Check
It answers the question: Is the application running? Example path: /health/live. If the process is alive, it returns 200 OK.
Readiness Check
It answers the question: Can the application serve requests right now? The readiness check verifies dependencies such as databases, message queues, payment services, and external APIs.
Program.cs — health checks
Example: /health/live returns 200 OK with Healthy, while /health returns 503 Service Unavailable, because the payments dependency is unavailable. The response explains which dependency failed.
ASP.NET Core Example
builder.Services.AddHealthChecks()
.AddCheck("database", () => HealthCheckResult.Healthy())
.AddCheck("payments", () => HealthCheckResult.Unhealthy());
app.MapHealthChecks("/health");
RED Metrics
Logs explain individual events. Metrics show overall system performance. A popular monitoring approach is RED Metrics:
Rate
How many requests are received. Example: 500 requests per minute
Errors
The percentage of requests that fail. Example: 2% 5xx responses
Duration
How long requests take. Measure the duration using p95 rather than averages.
RED metrics track incoming traffic, failures, and response time.
Metrics.cs — RED metrics
Results:
GET /menu
The results are: 0% errors, Average: 30ms and p95: 90ms.
POST /orders
The results are: 40% errors, Average: 220ms and p95: 440ms.
Grouping by application version shows: Version 2.4 → 0 errors and Version 2.3 → 4 errors.
The root cause becomes clear. Only version 2.3 is failing.
Why p95 Matters
The average hides slow requests.
Example: there are 10 requests. 9 requests = 20ms, and 1 request = 400ms. The average is 58ms, so the average looks acceptable. But the slow customer experienced 400ms.
p95 helps reveal those slow experiences.
Logs vs Metrics vs Health Checks
| Tool | Purpose |
|---|---|
| Logs | Explain individual events |
| Metrics | Measure system trends over time |
| Health Checks | Show whether the application can currently serve requests |
| Correlation IDs | Link related events together |
| Traces | Follow requests across multiple services |
You need all of them to operate a production system effectively.
Where You See This
- Azure Application Insights, Grafana, Datadog, and similar platforms collect logs and metrics automatically.
- Kubernetes uses liveness and readiness probes to restart unhealthy containers.
- Support teams ask customers for correlation ids to investigate problems.
- Mobile development teams group failures by app version.
- Production systems use RED metrics to detect outages before users report them.
Common mistakes
| Symptom | Cause | Fix |
|---|---|---|
| Logs do not explain failures | Logs contain only plain text | Use structured logging |
| Related events cannot be connected | No correlation id exists | Add correlation-id middleware |
| Traffic continues reaching unhealthy services | Readiness checks are incomplete | Verify dependencies in readiness checks |
| Customers report slowness but dashboards look healthy | Only averages are monitored | Track p95 and p99 latency |
| Secrets appear in log systems | Sensitive information is logged | Remove tokens, passwords, and private data from logs |
| Bugs affect one client version for weeks | Errors are not grouped by app version | Include version information in logs and metrics |
Exercises
What to Remember
- You cannot fix what you cannot see. Logs, metrics and health checks let you see.
- Log structured entries with named fields, and never log secrets.
- A correlation id ties together every log line of one request.
- Liveness says that the process runs. Readiness says that it can serve customers. Return
503when it cannot. - Watch Rate, Errors and Duration for each endpoint, and use p95, not the average.
Next: API Testing. You will write automated tests that check every endpoint on every change, so that a bug never comes back.