Introduction
Les fichiers de logs contiennent des horodatages dans de nombreux formats différents. Savoir les parser correctement est essentiel pour l'analyse de logs, le monitoring et le débogage.
Ce que Vous Apprendrez
- ✅ Formats courants d'horodatages dans les logs
- ✅ Expressions régulières pour chaque format
- ✅ Code de parsing en Python et JavaScript
- ✅ Normalisation vers format standard
- ✅ Gestion des fuseaux horaires
Formats de Log Courants
1. Apache/Nginx (CLF - Common Log Format)
[01/Dec/2024:10:15:30 +0000]
Regex :
REGEX1\[(\d{2}/\w{3}/\d{4}:\d{2}:\d{2}:\d{2} [+-]\d{4})\]
Python :
PYTHON1from datetime import datetime 2 3def parse_apache(timestamp_str): 4 # Exemple : "01/Dec/2024:10:15:30 +0000" 5 return datetime.strptime( 6 timestamp_str, 7 "%d/%b/%Y:%H:%M:%S %z" 8 ) 9 10log_line = '[01/Dec/2024:10:15:30 +0000] "GET / HTTP/1.1" 200' 11match = re.search(r'\[([^\]]+)\]', log_line) 12if match: 13 dt = parse_apache(match.group(1)) 14 print(dt.isoformat())
2. ISO 8601 / RFC 3339
2024-12-01T10:15:30Z
2024-12-01T10:15:30+01:00
Regex :
REGEX1\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:?\d{2})
JavaScript :
JAVASCRIPT1function parseIso8601(timestampStr) { 2 return new Date(timestampStr); 3} 4 5// Exemple 6const dt = parseIso8601("2024-12-01T10:15:30Z"); 7console.log(dt.toISOString());
3. Syslog (RFC 3164)
Dec 1 10:15:30 hostname app[123]: message
Note : Ce format N'inclut PAS l'année ni le fuseau horaire.
Python :
PYTHON1from datetime import datetime 2 3def parse_syslog(timestamp_str, year=None): 4 # Exemple : "Dec 1 10:15:30" 5 if year is None: 6 year = datetime.now().year 7 8 dt = datetime.strptime(timestamp_str, "%b %d %H:%M:%S") 9 return dt.replace(year=year) 10 11# Extraire du log 12import re 13log_line = "Dec 1 10:15:30 serveur app[123]: erreur" 14match = re.match(r'^(\w{3}\s+\d{1,2}\s\d{2}:\d{2}:\d{2})', log_line) 15if match: 16 dt = parse_syslog(match.group(1), year=2024)
4. Unix Timestamp
1701425730
1701425730000
JavaScript :
JAVASCRIPT1function parseUnixTimestamp(raw) { 2 const str = String(raw); 3 if (str.length === 10) { 4 return new Date(Number(raw) * 1000); 5 } else if (str.length === 13) { 6 return new Date(Number(raw)); 7 } 8 throw new Error('Format inconnu'); 9}
Parser Universel
Python
PYTHON1from datetime import datetime, timezone 2from dateutil import parser as dateutil_parser 3import re 4 5def parse_log_timestamp(raw: str) -> datetime: 6 """Parser universel pour horodatages de logs""" 7 s = raw.strip() 8 9 # 1. Essayer ISO 8601 / RFC 3339 10 try: 11 dt = dateutil_parser.isoparse(s) 12 if dt.tzinfo is None: 13 dt = dt.replace(tzinfo=timezone.utc) 14 return dt 15 except: 16 pass 17 18 # 2. Apache/Nginx: [01/Dec/2024:10:15:30 +0000] 19 if s.startswith('[') and s.endswith(']'): 20 inner = s[1:-1] 21 dt = datetime.strptime(inner, "%d/%b/%Y:%H:%M:%S %z") 22 return dt 23 24 # 3. Unix timestamp numérique 25 if s.isdigit(): 26 n = len(s) 27 if n == 10: 28 return datetime.fromtimestamp(int(s), tz=timezone.utc) 29 if n == 13: 30 return datetime.fromtimestamp(int(s)/1000, tz=timezone.utc) 31 32 raise ValueError(f"Format non reconnu : {raw}")
Normalisation
Normalisez toujours vers un format standard après parsing :
PYTHON1def normaliser_timestamp(dt: datetime) -> dict: 2 """Normalise datetime vers formats utiles""" 3 utc = dt.astimezone(timezone.utc) 4 return { 5 'iso': utc.isoformat(), 6 'unix_s': int(utc.timestamp()), 7 'unix_ms': int(utc.timestamp() * 1000), 8 'utc': utc 9 }
Meilleures Pratiques
- Parsez en UTC d'abord - Évite les problèmes de fuseau horaire
- Validez la plage - Rejetez les dates implausibles
- Gérez les années manquantes - Syslog n'inclut pas l'année
- Utilisez des bibliothèques éprouvées - Ne réinventez pas la roue
- Enregistrez les erreurs de parsing - Pour le débogage
Résumé
Vous avez appris à parser les horodatages de :
- Apache/Nginx (CLF)
- ISO 8601 / RFC 3339
- Syslog
- Unix timestamps
Utilisez notre Convertisseur par Lots pour traiter plusieurs horodatages !