Récupérer les Journaux d'Appareils sur macOS
macOS fournit un système de journalisation unifié puissant qui capture des informations détaillées sur les processus système, applications et activités utilisateur. Ce tutoriel montre comment collecter et analyser efficacement les journaux d'appareils dans votre MacFleet pour le dépannage, la surveillance de sécurité et l'analyse de performance.
Comprendre la Journalisation macOS
macOS utilise le système de journalisation unifié introduit dans macOS 10.12, qui consolide diverses sources de journaux :
- Journaux système - Noyau, services système et démons
- Journaux d'applications - Applications utilisateur et processus d'arrière-plan
- Journaux de sécurité - Authentification, autorisation et événements de sécurité
- Journaux réseau - Activité réseau et connectivité
Commandes de Journal de Base
Voir les Journaux Système Récents
#!/bin/bash
# Afficher les journaux de la dernière minute
sudo log show --last 1m
# Afficher les journaux de la dernière heure
sudo log show --last 1h
# Afficher les journaux du dernier jour
sudo log show --last 1d
Diffusion de Journaux en Direct
#!/bin/bash
# Diffuser les journaux en direct
sudo log stream
# Diffuser avec horodatage
sudo log stream --info --debug
Journaux Spécifiques aux Applications
Obtenir les Journaux pour une Application Spécifique
#!/bin/bash
# Requête de journal d'app basique
log show --predicate 'processImagePath CONTAINS[c] "safari"'
# Requête avec plage de temps
log show --predicate 'processImagePath CONTAINS[c] "Finder"' --last 30m
# Sauvegarder les journaux d'app dans un fichier
log show --predicate 'processImagePath CONTAINS[c] "Mail"' --last 1h > ~/Desktop/mail_logs.txt
Script de Collection de Journaux Entreprise
#!/bin/bash
# Script de Collection de Journaux d'Appareils pour MacFleet
# Compatible avec macOS 10.14+
# Configuration
LOG_DIR="/var/log/macfleet_logs"
TIMESTAMP=$(date '+%Y%m%d_%H%M%S')
HOSTNAME=$(hostname -s)
OUTPUT_DIR="$LOG_DIR/${HOSTNAME}_${TIMESTAMP}"
ARCHIVE_NAME="${HOSTNAME}_logs_${TIMESTAMP}.tar.gz"
# Fonction pour enregistrer les messages
log_message() {
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOG_DIR/collection.log"
}
# Fonction pour créer le répertoire de sortie
setup_directories() {
if mkdir -p "$OUTPUT_DIR"; then
log_message "✓ Répertoire de sortie créé : $OUTPUT_DIR"
return 0
else
log_message "✗ Échec de la création du répertoire de sortie"
return 1
fi
}
# Fonction pour collecter les journaux système
collect_system_logs() {
log_message "Collecte des journaux système..."
# Journaux système récents (dernières 24 heures)
if log show --last 24h > "$OUTPUT_DIR/system_logs_24h.log"; then
log_message "✓ Journaux système collectés (24h)"
else
log_message "✗ Échec de la collecte des journaux système"
fi
# Journaux critiques et d'erreur uniquement
if log show --last 24h --predicate 'messageType == 16 OR messageType == 17' > "$OUTPUT_DIR/critical_errors.log"; then
log_message "✓ Journaux critiques/erreurs collectés"
else
log_message "✗ Échec de la collecte des journaux critiques"
fi
# Journaux de démarrage
if log show --predicate 'process == "kernel"' --last 7d > "$OUTPUT_DIR/kernel_logs.log"; then
log_message "✓ Journaux du noyau collectés"
else
log_message "✗ Échec de la collecte des journaux du noyau"
fi
}
# Fonction pour collecter les journaux d'applications
collect_app_logs() {
log_message "Collecte des journaux d'applications..."
# Applications communes à surveiller
local apps=("Safari" "Finder" "Mail" "Calendar" "Contacts" "Notes" "Spotlight" "WindowServer")
for app in "${apps[@]}"; do
local output_file="$OUTPUT_DIR/${app,,}_logs.log"
if log show --predicate "processImagePath CONTAINS[c] \"$app\"" --last 24h > "$output_file" 2>/dev/null; then
# Garder le fichier seulement s'il a du contenu
if [[ -s "$output_file" ]]; then
log_message "✓ Journaux $app collectés"
else
rm -f "$output_file"
log_message "! Aucun journal trouvé pour $app"
fi
else
log_message "✗ Échec de la collecte des journaux $app"
fi
done
}
# Fonction pour collecter les journaux de sécurité
collect_security_logs() {
log_message "Collecte des journaux de sécurité..."
# Journaux d'authentification
if log show --predicate 'category == "authorization" OR process == "authd"' --last 7d > "$OUTPUT_DIR/auth_logs.log"; then
log_message "✓ Journaux d'authentification collectés"
else
log_message "✗ Échec de la collecte des journaux d'auth"
fi
# Événements de connexion/déconnexion
if log show --predicate 'eventMessage CONTAINS "login" OR eventMessage CONTAINS "logout"' --last 7d > "$OUTPUT_DIR/login_events.log"; then
log_message "✓ Événements de connexion collectés"
else
log_message "✗ Échec de la collecte des événements de connexion"
fi
}
# Fonction pour collecter les informations système
collect_system_info() {
log_message "Collecte des informations système..."
{
echo "=== Informations Système ==="
echo "Nom d'hôte : $(hostname)"
echo "Version macOS : $(sw_vers -productVersion)"
echo "Build : $(sw_vers -buildVersion)"
echo "Uptime : $(uptime)"
echo "Date : $(date)"
echo ""
echo "=== Informations Matériel ==="
system_profiler SPHardwareDataType
echo ""
echo "=== Usage Disque ==="
df -h
echo ""
echo "=== Usage Mémoire ==="
vm_stat
echo ""
echo "=== Processus en Cours ==="
ps aux | head -20
} > "$OUTPUT_DIR/system_info.txt"
log_message "✓ Informations système collectées"
}
# Fonction pour créer une archive
create_archive() {
log_message "Création de l'archive..."
cd "$LOG_DIR" || return 1
if tar -czf "$ARCHIVE_NAME" "$(basename "$OUTPUT_DIR")"; then
log_message "✓ Archive créée : $LOG_DIR/$ARCHIVE_NAME"
# Nettoyer le répertoire temporaire
rm -rf "$OUTPUT_DIR"
log_message "✓ Fichiers temporaires nettoyés"
# Afficher la taille de l'archive
local size
size=$(du -h "$LOG_DIR/$ARCHIVE_NAME" | cut -f1)
log_message "Taille de l'archive : $size"
return 0
else
log_message "✗ Échec de la création de l'archive"
return 1
fi
}
# Fonction pour télécharger l'archive (placeholder pour intégration entreprise)
upload_archive() {
local archive_path="$LOG_DIR/$ARCHIVE_NAME"
# Exemple : Télécharger vers serveur de journalisation central
# Remplacer par votre mécanisme de téléchargement actuel
log_message "Archive prête pour collecte : $archive_path"
# Placeholder pour logique de téléchargement
# scp "$archive_path" user@logserver:/logs/
# curl -F "file=@$archive_path" https://logserver.company.com/upload
return 0
}
# Fonction d'exécution principale
main() {
log_message "=== Début de la collecte de journaux MacFleet ==="
# Configuration
if ! setup_directories; then
exit 1
fi
# Collecter les journaux
collect_system_logs
collect_app_logs
collect_security_logs
collect_system_info
# Créer l'archive
if create_archive; then
upload_archive
log_message "=== Collecte de journaux terminée avec succès ==="
exit 0
else
log_message "=== Échec de la collecte de journaux ==="
exit 1
fi
}
# Exécuter la fonction principale
main "$@"
Scripts de Collection de Journaux Rapide
Collecter les Journaux pour une Période Spécifique
#!/bin/bash
# Collecter les journaux entre des dates spécifiques
START_DATE="2025-01-01"
END_DATE="2025-01-02"
OUTPUT_FILE="~/Desktop/logs_${START_DATE}_to_${END_DATE}.txt"
log show --start "$START_DATE" --end "$END_DATE" > "$OUTPUT_FILE"
echo "Journaux sauvegardés dans : $OUTPUT_FILE"
Collecter les Journaux de Crash d'Applications
#!/bin/bash
# Collecter les rapports de crash
CRASH_DIR="~/Library/Logs/DiagnosticReports"
OUTPUT_DIR="~/Desktop/crash_logs"
mkdir -p "$OUTPUT_DIR"
find "$CRASH_DIR" -name "*.crash" -mtime -7 -exec cp {} "$OUTPUT_DIR/" \;
echo "Journaux de crash récents copiés dans : $OUTPUT_DIR"
Surveiller des Événements Spécifiques
#!/bin/bash
# Surveiller les connexions de périphériques USB
log stream --predicate 'eventMessage CONTAINS "USB"' --info
# Surveiller les changements réseau
log stream --predicate 'subsystem == "com.apple.network"' --info
# Surveiller les événements du système de fichiers
log stream --predicate 'subsystem == "com.apple.filesystem"' --debug
Scripts d'Analyse de Journaux
Analyser les Événements d'Authentification
#!/bin/bash
# Extraire les tentatives de connexion échouées
log show --predicate 'eventMessage CONTAINS "authentication failure"' --last 7d \
| grep -E "(authentication failure|failed)" \
| sort | uniq -c | sort -nr > ~/Desktop/failed_logins.txt
echo "Analyse des connexions échouées sauvegardée dans ~/Desktop/failed_logins.txt"
Statistiques d'Usage d'Applications
#!/bin/bash
# Analyser les lancements d'applications
log show --predicate 'process == "launchd" AND eventMessage CONTAINS "spawn"' --last 24h \
| grep -oE '"[^"]*\.app"' \
| sort | uniq -c | sort -nr > ~/Desktop/app_usage.txt
echo "Statistiques d'usage d'applications sauvegardées dans ~/Desktop/app_usage.txt"
Gestion des Archives de Journaux
Créer une Archive de Journal Système
#!/bin/bash
# Créer une archive complète des journaux système
ARCHIVE_PATH="~/Desktop/SystemLogs_$(date +%Y%m%d_%H%M%S).logarchive"
log collect --output "$ARCHIVE_PATH" --last 24h
echo "Archive des journaux système créée : $ARCHIVE_PATH"
Voir les Journaux Archivés
#!/bin/bash
# Voir les journaux depuis l'archive
ARCHIVE_PATH="~/Desktop/SystemLogs.logarchive"
if [[ -f "$ARCHIVE_PATH" ]]; then
log show --archive "$ARCHIVE_PATH" --last 1h
else
echo "Archive non trouvée : $ARCHIVE_PATH"
fi
Dépannage des Problèmes Courants
Problème | Solution |
---|---|
Permission refusée | Exécuter avec sudo pour les journaux système |
Aucun journal trouvé | Vérifier la plage de dates et les prédicats |
Gros fichiers de journaux | Utiliser des filtres de temps et prédicats spécifiques |
Timeouts de script | Réduire la plage de temps ou utiliser la collecte asynchrone |
Corruption d'archive | Vérifier l'espace disque et les permissions |
Exemples de Filtrage de Journaux
Filtrer par Niveau de Journal
# Messages d'erreur uniquement
log show --predicate 'messageType == 16' --last 1h
# Messages info et debug
log show --predicate 'messageType >= 1' --last 30m
# Erreurs critiques uniquement
log show --predicate 'messageType == 17' --last 24h
Filtrer par Processus
# Processus système
log show --predicate 'process == "kernel" OR process == "launchd"' --last 1h
# Processus utilisateur
log show --predicate 'processImagePath BEGINSWITH "/Applications"' --last 1h
# Démons d'arrière-plan
log show --predicate 'processImagePath CONTAINS "daemon"' --last 1h
Considérations de Sécurité
- Confidentialité - Être attentif aux données utilisateur dans les journaux
- Rétention - Implémenter la rotation et le nettoyage des journaux
- Contrôle d'accès - Restreindre l'accès aux journaux au personnel autorisé
- Chiffrement - Chiffrer les archives de journaux avant transmission
- Conformité - Suivre les politiques de rétention des données
Conseils de Performance
- Utiliser des plages de temps spécifiques pour limiter le volume de données
- Filtrer par processus ou catégorie pour réduire le bruit
- Diffuser les journaux en temps réel pour une analyse immédiate
- Compresser les archives pour économiser l'espace de stockage
- Programmer la collecte régulière de journaux pendant les heures creuses
Notes Importantes
- Les journaux système peuvent contenir des informations sensibles
- Les grandes plages de temps peuvent générer des fichiers de journaux massifs
- Certains journaux nécessitent des privilèges admin pour l'accès
- La collecte de journaux peut impacter les performances système
- Tester les scripts sur des appareils individuels avant le déploiement de flotte