Slide 1

Slide 1 text

Vos logs méritent mieux que la config par défaut Grégoire Pineau dev-ops @jolicode & @redirectionio core team @symfony github.com/lyrixx twitter.com/lyrixx

Slide 2

Slide 2 text

2 Les logs, un sujet passionnant

Slide 3

Slide 3 text

3

Slide 4

Slide 4 text

En trois points L’observabilité 4

Slide 5

Slide 5 text

Les metrics mesurent ce qu’il se passe Donnée structurée Stockées dans une TSDB Les traces Les trois piliers de l’observabilité expliquent ce qu'il se passe Donnée non structurée (texte) ou structurée (json) Stockés dans un «journal» Les logs montrent ce qu’il se passe Donnée structurée Stockées dans une DB 5

Slide 6

Slide 6 text

Les logs 6

Slide 7

Slide 7 text

Les logs Exemple avec Kibana 7

Slide 8

Slide 8 text

Les metrics Exemple avec Grafana 8

Slide 9

Slide 9 text

Les traces Exemple avec Symfony 9

Slide 10

Slide 10 text

Pourquoi logger ? 10 1. logger ? 2. logguer ? 3. loger ? 4. loguer ?

Slide 11

Slide 11 text

11 Pour debugger ● Suivre un flow d'exécution ● Comprendre du code ● Trouver les bugs ● Résoudre les bugs ? ProTips

Slide 12

Slide 12 text

Pour alerter et monitorer 12 ● Recevoir un mail pour chaque nouvelle erreur ● Recevoir une notification Slack ● Envoyer ses logs vers ○ Produit SaaS ■ Sentry ■ Datadog ■ … ○ Base de données ■ Loki ■ Elasticsearch ■ ClickHouse ■ … ● …

Slide 13

Slide 13 text

Anatomie d’un log 13

Slide 14

Slide 14 text

14 Un standard ● PSR3 : psr/log@v3 ● LoggerInterface ● AbstractLogger + LoggerTrait ● NullLogger ● Des LogLevels ● Et une exception : InvalidArgumentException ● Et du tooling pratique 🥺

Slide 15

Slide 15 text

LoggerInterface 15

Slide 16

Slide 16 text

LogLevel 16 ⭐ debug information pour le debug ⭐ info événement intéressant ⭐ notice événement intéressant, mais occasionnel warning événement occasionnel, mais qui n’impacte pas l’utilisateur ❗ error Erreur lors de l'exécution critical Erreur grave, qui doit être résolue le plus rapidement alert Erreur grave, qui doit être résolue encore plus rapidement emergency WTF OMG BBQ !!! plus rien ne marche

Slide 17

Slide 17 text

LoggerInterface 17

Slide 18

Slide 18 text

Un standard, un context, et une exception 18 #[SensitiveParameter] $ready ProTips

Slide 19

Slide 19 text

Monolog 19 Le logger par défaut de Symfony

Slide 20

Slide 20 text

20 Monolog API

Slide 21

Slide 21 text

21 Monolog API

Slide 22

Slide 22 text

22 Dans Symfony

Slide 23

Slide 23 text

Comment bien logger ? 23

Slide 24

Slide 24 text

24 Comment bien écrire une ligne de log ? ● Mettre un message simple, clair, et descriptif ● Ne pas mettre de variable dans le message ○ Ajouter autant de contexte que nécessaire ● En cas d’erreur, le message doit être unique au sein de l’application ● Bonus ○ Finir par un point, comme les Exceptions 🙃 ○ Mettre une URL vers une page de documentation

Slide 25

Slide 25 text

Où logger ? 25 ● Partout, vraiment, partout ● Encore plus dans les crons, workers, processus async ● Dans les workflows critiques ou complexes : ○ un message “notice” avant : “Trying to do something” + un context bien rempli ○ des messages “info” pour les embranchements de code ○ un message “debug” après : “Did something” ○ un message si une erreur survient “cannot do something” + l’exception en context

Slide 26

Slide 26 text

Signaler tout ce qui est suspect 26 ● Dans un worker, quand une entité n’existe plus, niveau “warning” ● Un valeur de retour d’API suspecte : “warning” ou “error” ● Un fichier manque sur S3, un cache est vide alors qu’il devrait être chaud ● …

Slide 27

Slide 27 text

Mais aussi quand ça se passe bien 27 ● C’est important de savoir qu’une action est en success ● Cela prouve que le code s’est bien exécuté jusqu’au bout

Slide 28

Slide 28 text

28 Les «processors» ● Modifier les logs ● Enrichir les logs

Slide 29

Slide 29 text

Serialization du context 29

Slide 30

Slide 30 text

ProcessorInterface 30

Slide 31

Slide 31 text

ModelProcessor 31

Slide 32

Slide 32 text

ModelProcessor 32

Slide 33

Slide 33 text

ModelProcessor 33

Slide 34

Slide 34 text

Autres processors utiles 34 ● Mes préférés: ○ Symfony\Bridge\Monolog\Processor\WebProcessor ○ Symfony\Bridge\Monolog\Processor\ConsoleCommandProcessor ○ Symfony\Bridge\Monolog\Processor\TokenProcessor ● Mais il en existe plein d’autres : https://github.com/Seldaek/monolog/blob/main/doc/02-handlers-formatt ers-processors.md#processors

Slide 35

Slide 35 text

Autres processor utiles - Configuration 35

Slide 36

Slide 36 text

Quelques créations 🎨 - AmqpEnvelopeProcessor 36

Slide 37

Slide 37 text

Quelques créations 🎨 - SapiProcessor 37

Slide 38

Slide 38 text

Quelques créations 🎨 - UuidProcessor 38 UuidProcessor ● Ajoute un identifiant unique à tous les logs pour une requête ou un message messenger ● Mais permet d'être remplacé si une en-tête HTTP est présente ● Transmet cet identifiant à un message (messenger) pour conserver l'intégralité de la trace ● Plug & Play ● https://s.lyrixx.info/log-uuid-processor

Slide 39

Slide 39 text

Exemple de log 39

Slide 40

Slide 40 text

40

Slide 41

Slide 41 text

41 Organiser ses logs Avec des channels

Slide 42

Slide 42 text

42 Channels ● Un channel est un journal de logs ● Il existe différents channels par défaut : asset, cache, console, doctrine, event, http, lock, mailer, messenger, php, profiler, request, router, security, semaphore, translation, workflow ● L’application utilise le channel “app” par défaut ● Et vous pouvez créer les vôtres

Slide 43

Slide 43 text

Channels personnalisés 43

Slide 44

Slide 44 text

Channels personnalisés 44

Slide 45

Slide 45 text

45 Envoyer ses logs Avec des handlers

Slide 46

Slide 46 text

46 Les handlers Elasticsearch … DataDog var/log/prod.log Sentry Your app Monolog

Slide 47

Slide 47 text

Différents groupe de handlers 47 ● Monolog fournit une très grande liste de handlers ○ stream (file), socket (tcp/udp), amqp, syslog, … ○ mail, Slack, IFTTT, Sendgrid, Telegram, … ○ Sentry, NewRelic, Logmatic, … ○ Redis, Doctrine, Elasticsearch, Elastica, MongoDB, … ○ Cependant, certains sont déconseillés ● Certains sont spéciaux ○ FingersCrossed ○ Group ○ Buffer ○ …

Slide 48

Slide 48 text

Transporter tous les logs 48 Comment transporter tous vos log à destination ? Tout dépend de la destination ! ● Via STDERR (Docker, PaaS) (StreamHandler) ● Via un fichier (bare metal, faible trafic) (StreamHandler) ○ ⚠ Mettre en place un log rotate (RotatingFileHandler) ● Via TCP, ou UDP (bare metal, fort trafic) (Syslog*Handler) ○ Vers un agrégateur local : ■ Vector ■ Logstash ■ Fluentd ■ FileBeat ● Via le handler du SaaS

Slide 49

Slide 49 text

Et des formatters 49 Va formater le LogRecord avant de l’envoyer ● line ● JSON ● HTML ● logstash ● …

Slide 50

Slide 50 text

50 Exemple de configuration

Slide 51

Slide 51 text

Les erreurs PHP ? 51 Avant Symfony 7.1 les notices et warning n’étaient pas remontés dans les logs au niveau erreur !

Slide 52

Slide 52 text

52 En dev

Slide 53

Slide 53 text

En prod 53

Slide 54

Slide 54 text

fingers crossed - activation strategy 54

Slide 55

Slide 55 text

En prod - certains channels sont toujours loggués 55

Slide 56

Slide 56 text

Deprecation 56 ● Symfony log les dépréciations dans un channel “deprecation” si il existe ● On peut utiliser un handler spécifique pour écrire les logs dans un fichier ○ Et pourquoi pas faire du sampling ● Attention à la facturation

Slide 57

Slide 57 text

57 Quel moteur de stockage ? ● L’alerting ● La recherche

Slide 58

Slide 58 text

58 L’alerting ● Quand quelque chose se passe mal ○ Être prévenu le plus rapidement possible ○ Recevoir une alerte à la première occurrence d’une erreur ■ Sentry ■ BugSnag ■ …

Slide 59

Slide 59 text

La recherche 59 ● Pour analyser pourquoi ça s’est mal passé ○ ll faut un maximum de log et de contexte ● Mais où stocker tous ces logs ? ○ In house : ■ Elasticsearch + Kibana ■ Loki + Grafana ■ ClickHouse + Grafana ■ Signoz ■ Open observe ■ … ○ Produit - Saas ■ Datadog ■ NewRelic ■ … github.com/lyrixx/symfony-observability-demo

Slide 60

Slide 60 text

60 Conclusion

Slide 61

Slide 61 text

Conclusion 61 ● Logger un maximum ○ Utiliser le context avec des processor ○ Utiliser des channels, dont un pour l’audit log ○ Configurer les handlers en fonction des channels ● Utiliser de l’alerting ● Si possible, stocker les logs pour de l’analyse

Slide 62

Slide 62 text

62 Merci ! Grégoire Pineau dev-ops @jolicode & @redirectionio core team @symfony github.com/lyrixx twitter.com/lyrixx 🌲Qui a compris la relation entre le thème des slides et le sujet ? 🌲