Les pubs vous déplaisent ? Aller Sans pub Auj.

Journaux d'accès serveur — L'histoire de chaque requête que votre application a reçue

Mis à jour le

Chaque requête HTTP que votre serveur gère laisse une ligne dans le journal d'accès. Voici comment la lire — champ par champ — et quels motifs à surveiller.

Server Access Logs — The Story of Every Request Your App Has Received 1
ANNONCE · Supprimer ?

Every HTTP request your server handles leaves a line in the access log. Most of the time, these files sit on disk growing silently until a disk alert fires or something breaks in production. Then everyone suddenly wants to read them.

Here’s a single line from a server running the Combined Log Format:

203.0.113.42 - jsmith [09/May/2026:14:32:11 +0000] "GET /api/users/profile HTTP/1.1" 200 1843 "https://example.com/dashboard" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"

Eight fields. Each one is a piece of evidence about what happened. Let’s go left to right.

The Fields, One by One

1. Client IP — 203.0.113.42

The IP address that opened the TCP connection to your server. This is pas necessarily the end user’s IP. If you’re behind a load balancer, CDN, or reverse proxy (Nginx in front of a Node app, for example), this will be the proxy’s IP. The real client IP lives in the X-Forwarded-For ou X-Real-IP headers — and you have to explicitly configure your log format to capture them.

In Nginx, that looks like adding $http_x_forwarded_for to your log_format directive. In Apache, use %{X-Forwarded-For}i. If you skip this and then get hit with an abuse complaint or need to block a bad actor, you’ll find yourself staring at your own load balancer’s IP in every log line.

2. Ident — -

Always a dash. This field was meant to carry the result of an identd lookup — an ancient protocol (RFC 1413) that let servers ask the client’s OS who owned the process making the connection. Nobody runs identd anymore. The field exists because the Common Log Format was standardized when identd was still a thing. Skip it.

3. Auth User — jsmith

The username, populated when HTTP Basic Auth or Digest Auth is in play. For most modern apps — token auth, session cookies, JWTs — this will be a dash. If you protect an admin area with htpasswd, failed logins show as - next to a 401 status; successful ones show the username.

4. Timestamp — [09/May/2026:14:32:11 +0000]

The time the server finished handling the request (not when it started). Format is day/Mon/year:HH:MM:SS timezone. The timezone offset matters more than people realize — if your app server runs in UTC but your APM or alerting tool is in a local timezone, correlating a spike in logs with a specific incident requires conversion math every single time. Run everything in UTC.

5. Request Line — "GET /api/users/profile HTTP/1.1"

The most information-dense field. Three parts: the HTTP method, the path with query string, and the protocol version.

  • Méthode — GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS. Unexpected methods on an endpoint are worth noting.
  • Path + query string — tells you exactly what was requested. Query strings can contain search terms, IDs, and in poorly designed APIs, authentication tokens. Log accordingly.
  • Protocole — HTTP/1.0 clients in your logs in 2026 are either ancient integrations or something impersonating an old client. HTTP/2 and HTTP/3 log as those versions if your server supports them.

6. Status Code — 200

The HTTP status the server sent back. This is the verdict field.

  • 2xx — success. Request handled.
  • 3xx — redirect. Client needs to go somewhere else.
  • 4xx — client error. Bad request, missing auth, not found. Could be legitimate usage or probing.
  • 5xx — server error. Your app crashed, timed out, or returned garbage. Always investigate these.

When triaging an incident, filter by 5xx first. Then look at the timestamp of the first 500 — that’s when the failure started. Everything before that is the lead-up; everything after is the blast radius.

7. Bytes Sent — 1843

The size of the response body in bytes, not counting headers. A dash means zero bytes (typical for 304 Not Modified responses — the client already has the content). Unexpectedly large values on endpoints that should return a few hundred bytes is a red flag. An authenticated user hitting a “get my profile” endpoint and receiving 40MB is either a bug or someone’s abusing a data export.

8. Referer — "https://example.com/dashboard"

Where the client came from before making this request — the URL in the browser’s Referer header. (The HTTP spec misspelled it in 1996 and we’re stuck with it.) Direct traffic, bookmarks, and requests from native apps come in with an empty referer. This field only exists in the Combined Log Format; the original Common Log Format ends at bytes sent.

Referer spam — fake referer headers in bulk requests trying to show up in your analytics — used to be more common but is now mostly a relic. Still worth filtering from your aggregate stats.

9. User Agent — "Mozilla/5.0 (Windows NT 10.0; Win64; x64)…"

The client identifying itself. User agents are trivially spoofable, so treat this as a hint, not a fact. Legitimate crawlers usually identify honestly: Googlebot/2.1 (+http://www.google.com/bot.html), Bingbot/2.0. Scrapers impersonating browsers send the full Mozilla/5.0 Chrome string. Curl sends curl/8.x unless someone overrides it with -A.

Patterns to watch: identical user agent strings hitting the same endpoints at machine speed, or a user agent claiming to be iOS Safari but making requests in a pattern no human browser would (no images, no CSS, sequential product page crawls).

Patterns That Show Up in Every Log

The vulnerability scan

A single IP or small subnet hitting dozens of paths in rapid succession: /.env, /wp-login.php, /phpmyadmin, /admin/config.yml, /.git/config. All return 404. This is an automated scanner running a checklist, not a targeted attack. They run against every public IP constantly.

The right question isn’t “why are they scanning me” — it’s “did any of those paths return 200.” If /.env returns 200 on your server, that’s the actual problem.

# Check if any sensitive paths actually returned 200
grep -E '"(GET|POST) /(wp-login\.php|\.env|\.git/config|phpmyadmin|admin)' access.log | awk '$9 == 200'

Credential stuffing

High-volume POST requests to your login endpoint, almost all returning 401, from a distributed set of IPs. The giveaway is the pattern: same endpoint, consistent response size (the error page), many different source IPs that share an ASN. The response times tend to be consistent too — automated login attempts run at a steady rate to avoid rate limiting.

# Count POST /login attempts with 401 status by source IP
awk '$6 == "\"POST" && $7 == "/api/login" && $9 == "401" {print $1}' access.log \
  | sort | uniq -c | sort -rn | head -20

The 404 spike after a deploy

You deploy a new version. 404s spike. Old links in emails, bookmarks, and external sites are pointing to URLs that no longer exist. This is normal — but if the 404s are on URLs that should exist in the new version, that’s a routing regression. Compare the 404 paths against your route definitions.

Slow response clustering

The standard log format doesn’t include response time. You have to add it: in Apache, append %D (microseconds) to your LogFormat; in Nginx, add $request_time to your log_format block. Once you have it:

# Nginx: show requests slower than 3 seconds (request_time in last field)
awk '{if ($NF+0 > 3) print $0}' /var/log/nginx/access.log | head -20

If slow requests cluster around a specific time window, that’s contention — a cron job, a batch process, or a backup hammering the database. If a specific path is consistently slow regardless of time, that’s a slow query or a blocking I/O call that needs profiling.

Debugging an Incident From Logs

The access log is a timeline. When a user reports “something broke around 3pm,” you:

  • Filter to the 14:50–15:10 window
  • Look for the first 5xx — that’s when it started
  • Check what changed in the minutes before: was there a deploy? A config push? A cert renewal?
  • Look at which paths hit 5xx — is it everything or one endpoint?
  • Check the bytes-sent on successful responses before and after — did something start returning truncated responses?

A few failure signatures worth knowing:

  • 502 surge — your upstream died (app server crash, connection pool exhausted, database went down). The 502s start at a precise timestamp.
  • Redirect loop — 301/302 from the same IP to the same path repeatedly. Usually an HTTPS redirect misconfiguration or a Cloudflare SSL setting fighting with your app’s own redirect logic.
  • 200 with zero bytes — status 200 but bytes sent is 0 or -. Your app accepted the request, swallowed an exception, and returned an empty body. Classic unhandled error case.
  • 413 spike — clients sending request bodies over your size limit. Either your limit is too low for the use case or someone is probing for upload vulnerabilities.

If you’re dealing with logs in multiple formats — Apache Common, Apache Combined, Nginx default, custom formats — the Access Log Formatter can parse and annotate the fields so you’re not mentally mapping field positions every time you switch between servers.

Log Management You’ll Regret Not Setting Up

  • Log rotationlogrotate configured to rotate daily, compress, and keep 14–30 days. Without it, access.log grows until the disk fills. This happens in production.
  • Centralized logging — once you have more than one server, tailing individual log files doesn’t scale. Ship to Loki + Grafana, Elasticsearch, or a managed service. Structured JSON log format makes querying much easier than parsing CLF with awk.
  • Access control on raw logs — log files can contain query parameters with tokens, user PII, and internal paths. Don’t make them world-readable. Be deliberate about log retention periods if you’re under GDPR or similar.
  • Don’t log sensitive query params — if your app accepts auth tokens or passwords as URL parameters (it shouldn’t, but sometimes legacy APIs do), filter them at the log level before they hit disk.
Envie d'une expérience sans pub ? Passez à la version sans pub

Installez nos extensions

Ajoutez des outils IO à votre navigateur préféré pour un accès instantané et une recherche plus rapide

Sur Extension Chrome Sur Extension de bord Sur Extension Firefox Sur Extension de l'opéra

Le Tableau de Bord Est Arrivé !

Tableau de Bord est une façon amusante de suivre vos jeux, toutes les données sont stockées dans votre navigateur. D'autres fonctionnalités arrivent bientôt !

ANNONCE · Supprimer ?
ANNONCE · Supprimer ?
ANNONCE · Supprimer ?

Coin des nouvelles avec points forts techniques

Impliquez-vous

Aidez-nous à continuer à fournir des outils gratuits et précieux

Offre-moi un café
ANNONCE · Supprimer ?