Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

sys._current_frames(), Radiografando seu software em tempo real

162 views

Published on

Presentation at PythonBrasil 2013.

Apresentação na PythonBrasil[9]

Published in: Technology
  • Be the first to comment

  • Be the first to like this

sys._current_frames(), Radiografando seu software em tempo real

  1. 1. sys._current_frames() Radiografando seu software em tempo real Leonardo Rochael Almeida Soft. Eng. @ Geekie (We're Hiring!) © 2013 Leonardo Rochael Almeida, CC-BY-SA
  2. 2. Resumo ● sys._current_frames(): – ● Tracebacks a qualquer momento Tracebacks em sequência: – Diagnóstico rápido de performance © 2013 Leonardo Rochael Almeida, CC-BY-SA
  3. 3. Performance: melhores práticas ● Prevenção – Teste funcional de performance ● – testutils.org/multi-mechanize Antes de entrar em produção ● certo?! © 2013 Leonardo Rochael Almeida, CC-BY-SA
  4. 4. Performance: melhores práticas ● Produção – Espera a turba enfurecida ● – “Como reproduzir?” Monitoramento proativo © 2013 Leonardo Rochael Almeida, CC-BY-SA
  5. 5. Com instruções de reprodução ● “profile/cProfile” – Apenas “chamadas”, não “linhas” – Complicado: 57356 function calls (66 primitive calls) in 0.746 CPU seconds Ordered by: standard name ncalls 21 20 1 1 1 0 57291/21 21/1 tottime 0.000 0.000 0.001 0.000 0.000 0.000 0.743 0.001 percall 0.000 0.000 0.001 0.000 0.000 © 2013 Leonardo Rochael Almeida, CC-BY-SA 0.000 0.000 cumtime 0.000 0.000 0.001 0.744 0.746 0.000 0.743 0.744 percall 0.000 0.000 0.001 0.744 0.746 filename:lineno(function) :0(append) :0(extend) :0(setprofile) <string>:1(<module>) profile:0(print fib_seq(20); print) profile:0(profiler) 0.035 profile_fibonacci_raw.py:13(fib) 0.744 profile_fibonacci_raw.py:22(fib_seq)
  6. 6. Com instruções de reprodução ● “statprof” – Amostragem de tracebacks: ● – Estatísticas por linha Informação mais relevante que “cProfile” ● “line_profiler” ● Mas ainda não “contam a estória” © 2013 Leonardo Rochael Almeida, CC-BY-SA
  7. 7. Sem instruções de reprodução ● “profile/cProfile” – ● Pesado demais para produção Polvilhar temporização: – – Demorado... Restarts... – ● log(time.time() - start_time) Em produção?! DeadlockDebugger © 2013 Leonardo Rochael Almeida, CC-BY-SA
  8. 8. Monitoramento proativo ● Logs do servidor HTTP – Com informações de tempo ● Slow Queries no DB ● Insuficiente – Apenas polvilhando temporizações © 2013 Leonardo Rochael Almeida, CC-BY-SA
  9. 9. DeadlockDebugger ● Tracebacks de todas as threads ● URL especial ● Mesmo com o sistema travado © 2013 Leonardo Rochael Almeida, CC-BY-SA
  10. 10. Zope: pequeno resumo ● Z Object Publishing Environment ● Uma thread de escuta – – ● Destrincha requisição HTTP Põe na fila Poucas worker threads: – Calculam / renderizam a resposta © 2013 Leonardo Rochael Almeida, CC-BY-SA
  11. 11. DeadlockDebugger for thread_id, frame in sys._current_frames().items(): output = StringIO() traceback.print_stack(frame, file=output) res.append("Thread %s:n%s" % (thread_id, output.getvalue())) res.append("End of dump") return 'n'.join(res) © 2013 Leonardo Rochael Almeida, CC-BY-SA
  12. 12. sys._current_frames() ● Python dict – Chave: thread id (int) ● – Mesmo que thread.get_ident() em cada thread Valor: Top Stack Frame ● ● Executando agora nessa thread Topo da pilha de thread © 2013 Leonardo Rochael Almeida, CC-BY-SA
  13. 13. Stack Frame ● Função Atualmente executando – ● Arquivo e Nº de linha Variáveis – locals – globals ● Frame da Função que me chamou ● [...] © 2013 Leonardo Rochael Almeida, CC-BY-SA
  14. 14. Pra que serve o Frame? ● Obter valor de variáveis >>> a_list = range(5) >>> import sys, thread >>> thread_id = thread.get_ident() >>> frame = sys._current_frames()[thread_id] >>> frame.f_locals["a_list"] [0, 1, 2, 3, 4] © 2013 Leonardo Rochael Almeida, CC-BY-SA
  15. 15. Pra que serve o Frame? ● Avaliar código no contexto >>> eval("len(a_list)", frame.f_globals, frame.f_loc 5 © 2013 Leonardo Rochael Almeida, CC-BY-SA
  16. 16. Pra que serve o Frame? ● Imprimir todo o stack de uma thread >>> import traceback >>> traceback.print_stack(frame) File "[...]/bin/ipython", line 9, in <module> load_entry_point('ipython==0.13.2', 'console_scripts', 'ipython')() File "[...]/terminal/ipapp.py", line 389, in launch_new_instance app.start() [...] File "[...]/core/interactiveshell.py", line 2745, in run_code return outflag File "<ipython-input-5-f0e996c7314a>", line 1, in <module> frame = sys._current_frames()[thread_id] © 2013 Leonardo Rochael Almeida, CC-BY-SA
  17. 17. DeadlockDebugger ● Raio-X: – Thread: 1 ● – Stack trace … Thread: 2 ● Stack trace … © 2013 Leonardo Rochael Almeida, CC-BY-SA
  18. 18. DeadlockDebugger ● Muito bom se você está lá! – Senão, não ajuda muito... © 2013 Leonardo Rochael Almeida, CC-BY-SA
  19. 19. Dá pra melhorar? ● DeadlockDebugger contínuo ● Apenas em requisições lentas ● Com informação adicional – URL, POST, GET, Cookies... © 2013 Leonardo Rochael Almeida, CC-BY-SA
  20. 20. LongRequestLogger ● Criado na Nexedi ● Design – – Sébastien Robin – ● Julien Muchembled Leonardo Rochael Almeida Implementação p/ Zope2 – ● Leonardo Rochael Almeida Portado para WSGI por Shane Hathaway – PYPI: slowlog © 2013 Leonardo Rochael Almeida, CC-BY-SA
  21. 21. LongRequestLogger slowlog ● Intercepta e monitora cada requisição ● Logfile: – Request X, thread Y, running for T seconds ● ● – Request X, thread Y, running for T+2 seconds ● ● – Request Info Stack trace Request Info Stack trace [...] © 2013 Leonardo Rochael Almeida, CC-BY-SA
  22. 22. slowlog mostra ● Só requisições lentas – Não o “dano colateral” na fila ● Porque são lentas ● O local exato pra otimizar © 2013 Leonardo Rochael Almeida, CC-BY-SA
  23. 23. ERP5 Case Study ● “T-Shirt Custom Printing company” ● ERP5: ERP da Nexedi, em Zope ● MRP, CRM, Contabilidade, ... ● Picos de performance muito ruim ● Nunca na mesma URL duas vezes ● Sempre na “hora do rush” © 2013 Leonardo Rochael Almeida, CC-BY-SA
  24. 24. ERP5 Case Study ● Culpado: Sale Order Line Price ● Calculo sob demanda – ● Normalmente em Background Resolvido em 15 linhas © 2013 Leonardo Rochael Almeida, CC-BY-SA
  25. 25. Plone Case Study ● Grande portal governamental ● LongRequestLogger: – Lentidão em horários específicos – Culpado: gargalo no acesso ao banco – Na hora do backup ● Sobrecarga na interface de rede © 2013 Leonardo Rochael Almeida, CC-BY-SA
  26. 26. O que otimizar: Limite entre o frio e o quente ● Stack Trace em Tx – A ● – – – C(...) D(...) E(...) ● F(...) © 2013 Leonardo Rochael Almeida, CC-BY-SA G(...) G ● – C(...) C ● – B(...) B ● – E A ● – D ● – B(...) C ● Stack Trace em Tx + 2 – B ● ● H(...) H ● I(...)
  27. 27. Porque funciona? ● Profiling por amostragem ● Pura probabilidade – Quem é lento sempre aparece ● Stack traces (+dados) “contam a estória” ● Independencia do usuário © 2013 Leonardo Rochael Almeida, CC-BY-SA
  28. 28. Slowlog em Django ● mysite/wsgi.py: from django.core.wsgi import get_wsgi_application application = get_wsgi_application() # Apply WSGI middleware here. from slowlog.wsgi import SlowLogApp from mysite import settings application = SlowLogApp(application, logfile=settings.SLOWLOG_FILENAME) © 2013 Leonardo Rochael Almeida, CC-BY-SA
  29. 29. Slowlog em Pyramid ● paster.ini: pyramid.includes = [...] slowlog slowlog = true slowlog_file = %(here)s/tmp/slow.log © 2013 Leonardo Rochael Almeida, CC-BY-SA
  30. 30. Desafios ● Volume de dados – – ● Análise / classificação Desentrelaçamento (Ausência de) Interface de Usuário – grep – <seu editor de texto favorito> © 2013 Leonardo Rochael Almeida, CC-BY-SA
  31. 31. Melhorias futuras ● Análise – Busca / ordenação ● Mais info extraída dos frames ● Log estruturado – Comparações mais profundas entre stacks © 2013 Leonardo Rochael Almeida, CC-BY-SA
  32. 32. Questões em aberto ● Real impacto de performance – Quão curto pode ser o intervalo? – Contenção na GIL se muito curto? © 2013 Leonardo Rochael Almeida, CC-BY-SA
  33. 33. We're Hiring jobs@geekie.com.br © 2013 Leonardo Rochael Almeida, CC-BY-SA
  34. 34. Referencias ● SlowLog: https://pypi.python.org/pypi/slowlog ● LongRequestLogger: ● http://www.geekie.com.br ● @LeoRochael ● LeoRochael@geekie.com.br ● LeoRochael@gmail.com © 2013 Leonardo Rochael Almeida, CC-BY-SA

×