Paris RailsCamp 2009

962 vues

Publié le

An (old) Fotopedia presentation we gave at Paris RailsCamp 2009 about our log/error infrastructure

Publié dans : Technologie
0 commentaire
0 j’aime
Statistiques
Remarques
  • Soyez le premier à commenter

  • Soyez le premier à aimer ceci

Aucun téléchargement
Vues
Nombre de vues
962
Sur SlideShare
0
Issues des intégrations
0
Intégrations
2
Actions
Partages
0
Téléchargements
4
Commentaires
0
J’aime
0
Intégrations 0
Aucune incorporation

Aucune remarque pour cette diapositive















































  • Paris RailsCamp 2009

    1. 1. Logs, exceptions, mails, et autres désagréments L’architecture de data-mining et de remontée d’erreurs chez Fotonauts Olivier Gutknecht Aymerick Jéhanne Mathieu Poumeyrol olg@fotonauts.com aymerick@fotonauts.com kali@fotonauts.com
    2. 2. La Seule Vraie Question “euh , il s ’est p assé quoi, là ?”
    3. 3. La Seule Vraie Réponse les LOGS
    4. 4. 2 usages
    5. 5. Global et éternel • Toutes les machines • Sur tous les composants voulus • A tous les niveaux • Aussi longtemps que désiré • Analyse en batch • Usages applicatifs, business, métriques
    6. 6. Local et focalisé • Axé sur les situations d’erreur • Sur quelques composants (Rails, Merb) • Autant d’informations que possible • Persistence à court/moyen terme • Analyse minimal et quasi-live • Usage axé développement
    7. 7. ErrorMailerx e d u R
    8. 8. Idée Géniale #1 • Envoyons un mail à chaque exception Rails
    9. 9. Google tried to deliver your message, but it was rejected. The user you are trying to contact is receiving mail at a rate that prevents additional messages from being delivered.
    10. 10. Hey !
    11. 11. Solution 1 MPW-C Compiler ”Too many errors on one line (make fewer)”
    12. 12. Solution 1I Jean Cocteau “Puisque ces mystères me dépassent, feignons d'en être l'organisateur”
    13. 13. Une situation classique
    14. 14. irc://internal #infra <rapportr> [prod][amz-prod-xx.fotonauts.net] [picor][exception][error] No route matches "/hello-world" with {:method=>:get} Notification dans notre canal IRC interne
    15. 15. irc://internal #infra <rapportr> [prod][aws-prod-xx.fotonauts.net] [picor][exception][error] No route matches "/hello-world" with {:method=>:get} => http://xxx.fotonauts.net:5984/_utils/browse/ document.html?infra-events/ picor_exception_error_9b0b24e0- e817-012b-2ea4-12313800e821 ... avec le lien vers un document CouchDB
    16. 16. Inclusion directe du hash généré par Rails dans CouchDB
    17. 17. function(doc) { if (doc['data']['env']['HTTP_X_FORWARDED_FOR'] == "81.57.x.x, 127.0.0.1") emit(doc['date'], doc['message'])); } Définition ‘live’ d’une requête, conservable si besoin
    18. 18. Bono-bots Rails App stomp AMQP Exchange amqp amqp Toute action de haut niveau génère un message sur notre système bus Rapportr bots InfraLogger asynchrone / agents de traitements (bono-bots) pour gestion des notifications utilisateurs, etc... http irc On profite de la même infrastructure pour véhiculer les IRC Server CouchDB notifications d’exceptions.
    19. 19. Error “Mailer” def self.deliver_exception(exception) evt = { :app => 'picor', :type => 'exception', :level => 'error', :message => exception.message, :grid => grid, :fqdn => fqdn, } evt[:session][:params] = controller.params evt[:session][:env] = controller.request.env evt[:data][:backtrace] = exception.backtrace Bono::Bus::Infra.publish(Bono::Event.new(evt)) end
    20. 20. InfraBot - Couch class InfraLogger < Bono::Bot::Service::Base def start options = {:queue => "#{Bono::Bot.uid}.service.infra_logger"} @queue = Bono::Bus::Infra.watch_events(options) do |event| infra_event_received(event) end super end # callback fired when an infra event is received def infra_event_received(event) # format document doc = event.to_hash doc['_id'] = doc.delete('uid') # save to CouchDB database Bono::Database::CouchDB.store_document_async('infra-events', doc, 'infra_logger') end end
    21. 21. InfraBot - IRC class IrcLogger < Bono::Bot::Service::Base def start @c = EventMachine::connect(IRC_SERVER, IRC_PORT, BonoIrc, self) @c {|conn| conn.send_data("JOIN #infran") } @c do |conn| options = {:queue => "#{Bot.uid}.service.irc_logger.infra_events"} @infra_events_queue = Bono::Infra.watch_events(options) do |e| infra_event_received(e) end end end # callback fired when an infra event is received def infra_event_received(e) send_message(“#infra”, e.to_s) send_message(“#infra”, "http://xxx:5984/_utils/browse/document.html?infra-events/#{e}") end end
    22. 22. Idées en l’air • Si plus de n erreur sur action par jour Entrer un bug automatiquement • Si plus de n erreur sur user x Envoyer un mail d’investigation • Si plus de n tentatives d’attaque Blacklister l’IP pour x heures
    23. 23. Logs globaux
    24. 24. Usage final • Statistiques applicatif utilisateur • Page views, country views • Search • Rating, ... • Business metrics
    25. 25. Sources • Frontaux Web • Varnish / Nginx / Lighttpd • Rails • production.log • Log d’actions utilisateur haut niveau • Divers logs infrastructure • mysql-slow.log, ...
    26. 26. Flot de traitement • Acquérir les logs en place • Store-n-forward • Perennisation des logs bruts • Traitement itératif des logs bruts
    27. 27. Flot de traitement • Acquérir les logs en place : multitail • Store-n-forward : Scribe • Perennisation des logs bruts : S3 • Traitement itératif des logs bruts : Batchr
    28. 28. MySQL High-level Rails Log HTTP Log Log action log Multitail Multitail Scribe Scribe ScribeServer
    29. 29. Outils externes • EC2 / S3 : Amazon Web Services • Hadoop: Framework Map/Reduce • Hive: Data-mining sur Hadoop • Scribe: logger distribué / hiérarchique basé sur Thrift: RPC bas niveau très efficace
    30. 30. ScribeServer HDFS Uploader Hadoop/Hive S3 Analyzer Business Developer Web front-end Indexer Metrics Tools
    31. 31. Batchr • Acquisition des données “historiques” • Importation des données journalières en DFS Hadoop • Analyse des logs (GeoIP, comptage, ...) • Update historique + journalière • Réinjection S3 • Réinjection applicatif
    32. 32. Implémentation • Gestion globale du batch par Rake • Gestion des instances EC2 (setup cluster hadoop, gestion de l’erreur) • Import/Export S3 ←→ HDFS • Extraction/Analyse avec Hadoop/HIVE • Réinjection dans l’applicatifs (Ruby DBI)
    33. 33. Hadoop EC2 • Réécriture du setup des images Hadoop- EC2 en rake • Boot d’une image Ubuntu standard • Configuration Rake Net::SSH::Multi • Download d’un hadoop standard • Drivé par le clustermaster via rake
    34. 34. hadoop_ec2:setup hadoop_ec2:setup_os_instances hadoop_ec2:mkfs hadoop_ec2:local_execution_directory hadoop_ec2:setup_hadoop hadoop_ec2:run
    35. 35. hadoop_ec2:run batchr:hadoop_setup batchr:prepare_hive batchr:dfs_accesslog batchr:dfs_buslog batchr:dfs_old_datasets
    36. 36. GeoIPCountryWhois.csv batchr:dfs_ips batchr:dfs_geoips batchr:table_ips batchr:table_update_datasets batchr:table_old_datasets batchr:table_datasets
    37. 37. batchr:table_datasets batchr:dfs_datasets batchr:dfs_stats batchr:s3_datasets batchr:s3_stats batchr:app_stats batchr:daily_attempt
    38. 38. “Stateful Rake” • Rake • Expression des dépendances • Exécution manuelle d’une étape • Avec des ajouts... • Etapes intermédiaires non fiables • Qu’est-ce qu’une tache terminée ?
    39. 39. class TaskOnce < Rake::Task def execute(args) time = Time.now begin super(args) File.open(".done."+ name, "w") do |o| o.puts(Time.now - time).to_s + "sn" end rescue Exception => e File.open(".fail."+ name, "w") { |o| o.puts e.inspect } raise e end end def needed? !File.exist?(".done." + name) end end def once(args, &block) TaskOnce.define_task(args, &block) end
    40. 40. desc "extract unique ips from log" once :dfs_ips => :table_accesslog do @hadoop.hive_string <<-HIVE, "dfs_ips" INSERT OVERWRITE DIRECTORY 'ips' SELECT distinct(remote_addr_int) FROM accesslog SORT BY remote_addr_int HIVE end
    41. 41. desc "run me every day" task :daily do begin Rake::Task["batchr:daily_attempt"].invoke ensure Rake::Task["batchr:cleanup"].invoke end end desc "run me every day, no cleanup on error" task :daily_attempt => [ :pick_yesterday, :picor_stats, :s3_datasets, :statr_datasets ] do end
    42. 42. Idées en l’air • Vraie reprise sur panne (Cluster EC2) • Réconciliation de logs • Accès filtré à une fenêtre de logs • Web Rake (monitoring, dashboard, ...) • Frameworkiser EC2/Hadoop/Rake • Prototypage des requêtes data-mining • Quid de l’usage/pertinence de Hive ?

    ×