SlideShare ist ein Scribd-Unternehmen logo
1 von 34
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
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
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
Performance: melhores práticas
●

Produção
–

Espera a turba enfurecida
●

–

“Como reproduzir?”

Monitoramento proativo

© 2013 Leonardo Rochael Almeida,
CC-BY-SA
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)
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
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
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
DeadlockDebugger
●

Tracebacks de todas as threads

●

URL especial

●

Mesmo com o sistema travado

© 2013 Leonardo Rochael Almeida,
CC-BY-SA
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
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
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
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
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
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
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
DeadlockDebugger
●

Raio-X:
–

Thread: 1
●

–

Stack trace …

Thread: 2
●

Stack trace …

© 2013 Leonardo Rochael Almeida,
CC-BY-SA
DeadlockDebugger
●

Muito bom se você está lá!
–

Senão, não ajuda muito...

© 2013 Leonardo Rochael Almeida,
CC-BY-SA
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
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
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
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
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
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
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
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(...)
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
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
Slowlog em Pyramid
●

paster.ini:
pyramid.includes =
[...]
slowlog
slowlog = true
slowlog_file = %(here)s/tmp/slow.log

© 2013 Leonardo Rochael Almeida,
CC-BY-SA
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
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
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
We're Hiring

jobs@geekie.com.br

© 2013 Leonardo Rochael Almeida,
CC-BY-SA
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

Weitere ähnliche Inhalte

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

Strider CD - Deploy Contínuo com JavaScript
Strider CD -  Deploy Contínuo com JavaScriptStrider CD -  Deploy Contínuo com JavaScript
Strider CD - Deploy Contínuo com JavaScriptTaller Negócio Digitais
 
Criando microsserviços em PHP
Criando microsserviços em PHPCriando microsserviços em PHP
Criando microsserviços em PHPFlávio Lisboa
 
TDC2018SP | Trilha Serveless - Pra que SERVErless?
TDC2018SP | Trilha Serveless - Pra que SERVErless?TDC2018SP | Trilha Serveless - Pra que SERVErless?
TDC2018SP | Trilha Serveless - Pra que SERVErless?tdc-globalcode
 
MySQL em 10min - Alexandre Almeida HTI Tecnologia
MySQL em 10min - Alexandre Almeida HTI TecnologiaMySQL em 10min - Alexandre Almeida HTI Tecnologia
MySQL em 10min - Alexandre Almeida HTI TecnologiaMySQL Brasil
 
FISL14: Como domar uma fera de 1 TFlop que cabe na palma da sua mão!
FISL14: Como domar uma fera de 1 TFlop que cabe na palma da sua mão!FISL14: Como domar uma fera de 1 TFlop que cabe na palma da sua mão!
FISL14: Como domar uma fera de 1 TFlop que cabe na palma da sua mão!Intel Software Brasil
 
FISL14: Como domar uma fera de 1 TFlop que cabe na palma da sua mão!
FISL14: Como domar uma fera de 1 TFlop que cabe na palma da sua mão!FISL14: Como domar uma fera de 1 TFlop que cabe na palma da sua mão!
FISL14: Como domar uma fera de 1 TFlop que cabe na palma da sua mão!Luciano Palma
 
Dicas e Truques de Performance: Como obter o maximo do Windows Server 2008 R2...
Dicas e Truques de Performance: Como obter o maximo do Windows Server 2008 R2...Dicas e Truques de Performance: Como obter o maximo do Windows Server 2008 R2...
Dicas e Truques de Performance: Como obter o maximo do Windows Server 2008 R2...Rodrigo Immaginario
 
Google AppEngine: Desafios da adoção de cloud no mercado de seguros
Google AppEngine: Desafios da adoção de cloud no mercado de segurosGoogle AppEngine: Desafios da adoção de cloud no mercado de seguros
Google AppEngine: Desafios da adoção de cloud no mercado de segurosGustavo Concon
 
QCon SP 2015 - Advogados do diabo: como a arquitetura emergente de sua aplica...
QCon SP 2015 - Advogados do diabo: como a arquitetura emergente de sua aplica...QCon SP 2015 - Advogados do diabo: como a arquitetura emergente de sua aplica...
QCon SP 2015 - Advogados do diabo: como a arquitetura emergente de sua aplica...Gleicon Moraes
 
Conhecendo o Nodejs
Conhecendo o NodejsConhecendo o Nodejs
Conhecendo o NodejsCaio Cutrim
 
Entendendo o ZDLRA - Oracle Zero Data Loss Recovery Appliance e garantindo rp...
Entendendo o ZDLRA - Oracle Zero Data Loss Recovery Appliance e garantindo rp...Entendendo o ZDLRA - Oracle Zero Data Loss Recovery Appliance e garantindo rp...
Entendendo o ZDLRA - Oracle Zero Data Loss Recovery Appliance e garantindo rp...Weligton Pinto
 
Monitoramento da rede de A a ZABBIX - Daniel Bauermann
Monitoramento da rede de A a ZABBIX - Daniel BauermannMonitoramento da rede de A a ZABBIX - Daniel Bauermann
Monitoramento da rede de A a ZABBIX - Daniel BauermannTchelinux
 
Monitoramento rede
Monitoramento redeMonitoramento rede
Monitoramento redeAndré Déo
 
CV - JCP Maio 2015_Brasil_atz
CV - JCP Maio 2015_Brasil_atzCV - JCP Maio 2015_Brasil_atz
CV - JCP Maio 2015_Brasil_atzKarlos Paiva
 
Palestra: Computação Paralela na SECOMP 2013 (UNIFEI)
Palestra: Computação Paralela na SECOMP 2013 (UNIFEI)Palestra: Computação Paralela na SECOMP 2013 (UNIFEI)
Palestra: Computação Paralela na SECOMP 2013 (UNIFEI)Intel Software Brasil
 
Zabbix monitorando o zimbra collaboration 8.8 (1)
Zabbix   monitorando o zimbra collaboration 8.8 (1)Zabbix   monitorando o zimbra collaboration 8.8 (1)
Zabbix monitorando o zimbra collaboration 8.8 (1)PAULO R. DEOLINDO JUNIOR
 
TDC 2017 - Borg até o Prometheus: Site Reliability Engineering
TDC 2017 - Borg até o Prometheus: Site Reliability EngineeringTDC 2017 - Borg até o Prometheus: Site Reliability Engineering
TDC 2017 - Borg até o Prometheus: Site Reliability EngineeringFelipe Klerk Signorini
 

Ähnlich wie sys._current_frames(), Radiografando seu software em tempo real (20)

Strider CD - Deploy Contínuo com JavaScript
Strider CD -  Deploy Contínuo com JavaScriptStrider CD -  Deploy Contínuo com JavaScript
Strider CD - Deploy Contínuo com JavaScript
 
Criando microsserviços em PHP
Criando microsserviços em PHPCriando microsserviços em PHP
Criando microsserviços em PHP
 
TDC2018SP | Trilha Serveless - Pra que SERVErless?
TDC2018SP | Trilha Serveless - Pra que SERVErless?TDC2018SP | Trilha Serveless - Pra que SERVErless?
TDC2018SP | Trilha Serveless - Pra que SERVErless?
 
GDB e Análise de Bugs
GDB e Análise de BugsGDB e Análise de Bugs
GDB e Análise de Bugs
 
MySQL em 10min - Alexandre Almeida HTI Tecnologia
MySQL em 10min - Alexandre Almeida HTI TecnologiaMySQL em 10min - Alexandre Almeida HTI Tecnologia
MySQL em 10min - Alexandre Almeida HTI Tecnologia
 
FISL14: Como domar uma fera de 1 TFlop que cabe na palma da sua mão!
FISL14: Como domar uma fera de 1 TFlop que cabe na palma da sua mão!FISL14: Como domar uma fera de 1 TFlop que cabe na palma da sua mão!
FISL14: Como domar uma fera de 1 TFlop que cabe na palma da sua mão!
 
FISL14: Como domar uma fera de 1 TFlop que cabe na palma da sua mão!
FISL14: Como domar uma fera de 1 TFlop que cabe na palma da sua mão!FISL14: Como domar uma fera de 1 TFlop que cabe na palma da sua mão!
FISL14: Como domar uma fera de 1 TFlop que cabe na palma da sua mão!
 
Dicas e Truques de Performance: Como obter o maximo do Windows Server 2008 R2...
Dicas e Truques de Performance: Como obter o maximo do Windows Server 2008 R2...Dicas e Truques de Performance: Como obter o maximo do Windows Server 2008 R2...
Dicas e Truques de Performance: Como obter o maximo do Windows Server 2008 R2...
 
Google AppEngine: Desafios da adoção de cloud no mercado de seguros
Google AppEngine: Desafios da adoção de cloud no mercado de segurosGoogle AppEngine: Desafios da adoção de cloud no mercado de seguros
Google AppEngine: Desafios da adoção de cloud no mercado de seguros
 
QCon SP 2015 - Advogados do diabo: como a arquitetura emergente de sua aplica...
QCon SP 2015 - Advogados do diabo: como a arquitetura emergente de sua aplica...QCon SP 2015 - Advogados do diabo: como a arquitetura emergente de sua aplica...
QCon SP 2015 - Advogados do diabo: como a arquitetura emergente de sua aplica...
 
Redes2 aula02
Redes2 aula02Redes2 aula02
Redes2 aula02
 
Times plataforma-tdc2020
Times plataforma-tdc2020Times plataforma-tdc2020
Times plataforma-tdc2020
 
Conhecendo o Nodejs
Conhecendo o NodejsConhecendo o Nodejs
Conhecendo o Nodejs
 
Entendendo o ZDLRA - Oracle Zero Data Loss Recovery Appliance e garantindo rp...
Entendendo o ZDLRA - Oracle Zero Data Loss Recovery Appliance e garantindo rp...Entendendo o ZDLRA - Oracle Zero Data Loss Recovery Appliance e garantindo rp...
Entendendo o ZDLRA - Oracle Zero Data Loss Recovery Appliance e garantindo rp...
 
Monitoramento da rede de A a ZABBIX - Daniel Bauermann
Monitoramento da rede de A a ZABBIX - Daniel BauermannMonitoramento da rede de A a ZABBIX - Daniel Bauermann
Monitoramento da rede de A a ZABBIX - Daniel Bauermann
 
Monitoramento rede
Monitoramento redeMonitoramento rede
Monitoramento rede
 
CV - JCP Maio 2015_Brasil_atz
CV - JCP Maio 2015_Brasil_atzCV - JCP Maio 2015_Brasil_atz
CV - JCP Maio 2015_Brasil_atz
 
Palestra: Computação Paralela na SECOMP 2013 (UNIFEI)
Palestra: Computação Paralela na SECOMP 2013 (UNIFEI)Palestra: Computação Paralela na SECOMP 2013 (UNIFEI)
Palestra: Computação Paralela na SECOMP 2013 (UNIFEI)
 
Zabbix monitorando o zimbra collaboration 8.8 (1)
Zabbix   monitorando o zimbra collaboration 8.8 (1)Zabbix   monitorando o zimbra collaboration 8.8 (1)
Zabbix monitorando o zimbra collaboration 8.8 (1)
 
TDC 2017 - Borg até o Prometheus: Site Reliability Engineering
TDC 2017 - Borg até o Prometheus: Site Reliability EngineeringTDC 2017 - Borg até o Prometheus: Site Reliability Engineering
TDC 2017 - Borg até o Prometheus: Site Reliability Engineering
 

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

  • 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. 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. 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. Performance: melhores práticas ● Produção – Espera a turba enfurecida ● – “Como reproduzir?” Monitoramento proativo © 2013 Leonardo Rochael Almeida, CC-BY-SA
  • 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. 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. 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. 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. DeadlockDebugger ● Tracebacks de todas as threads ● URL especial ● Mesmo com o sistema travado © 2013 Leonardo Rochael Almeida, CC-BY-SA
  • 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. 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. 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. 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. 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. 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. 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. DeadlockDebugger ● Raio-X: – Thread: 1 ● – Stack trace … Thread: 2 ● Stack trace … © 2013 Leonardo Rochael Almeida, CC-BY-SA
  • 18. DeadlockDebugger ● Muito bom se você está lá! – Senão, não ajuda muito... © 2013 Leonardo Rochael Almeida, CC-BY-SA
  • 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. We're Hiring jobs@geekie.com.br © 2013 Leonardo Rochael Almeida, CC-BY-SA

Hinweis der Redaktion

  1. Diagnosing performance issues is usually one of the most difficult tasks for developers, specially when these performance issues are being reported by customers in production systems, which cannot easily be taken offline for instrumentation.
  2. Current status of performance monitoring in Python application is divided into what we do before the systems go into production and what we do after. At Nexedi, before systems go into production, we perform extensive “functional” performance tests. That is, full-stack tests that simulate typical scenarios of users interfacing with the system, including realistic pauses between accesses. These tests are played in parallel on a library built on top of “mechanize”. The number of parallel user simulations match (and surpasses) the expected use of the system according to the SLA agreement wit the client.
  3. After the system is put on production, performance issues invariably arrive, as not all combinations of system use can be predicted in advance. Aside of some Proactive Monitoring that can be added into the system, and of which we will talk more later on, the current status quo of performance monitoring can be summarized as: Wait for the angry mob to complain about the performance and then ask them for reproduction instructions. For without reproduction instructions it&apos;s very difficult to understand what is causing the system to be slow.
  4. The “statprof” module, which can be downloaded from PyPI, works differently than cProfile. Instead of being a deterministic profile and recording all calls, it&apos;s a sampling profile. It samples the call stack from time to time, accumulating and reporting on the lines that are present more often in the call stack. This is a marked improvement over cProfile as it shows which lines of the code are actually slow, thereby preserving more clearly the relationship between callers and callees. Being a sampling profile, it&apos;s performance impact is a lot lighter. However, by discarding the stack traces and only aggregating statistics, it also fails to completely “tell the story” of why the performance is slow, or why certain functions where called in a certain way.
  5. Without reproduction instructions, the best we can hope for is to be able to “corral” the performance issue by adding successive timing calls in the middle of the code. However doing this in the production environment is time consuming and is bound to cause conflicts with the system administrators who are, most of the time, responsible for making sure that you&apos;re not allowed to restart the server at your own fancy. In Zope land, there&apos;s a product called DeadlockDebugger, which is really useful when you can experience performance issues on your own, without the help from the client.
  6. But before we talk about DeadlockDebugger, we briefly must go over the architecture of Zope. It has a single thread that listens to HTTP requests, parses them and hands them over to a few Worker threads. These Worker threads are responsible for turning a request into a method call of an object, which is usually stored into Zope&apos;s object oriented Database, the ZODB. The ZODB is clusterable, w
  7. Logs do servidor HTTP Mostram URLs lentas Fila de Requisições → Falsos positivos Queries no DB Slow queries log
  8. Executed directly on the Listening thread. Works even when the system is completely blocked.
  9. Otherwise, you&apos;re just trying to train the angry mob to work for you.
  10. “statprofile” throws away exactly what is most valuable: The stack traces
  11. Captures even the most un-reproduceable Diagnose/Optimize before complaints
  12. GIL contention could be alleviated by monitoring all threads from a single additional thread. But not if the sampling itself is too heavy.