Título alternativo: How to get CPU usage per core with python
Teste de indexação do google
Mais um post para a série “Parseando o /proc” [1]. Dessa vez sem motivo explícito, apenas diversão!
Ambientes de testes:
Comparei os resultados através do htop e obtive uma proximidade alta nos valores, as diferenças se dão provavelmente pelo momento e duração da medição!
Quem puder testar em ambientes com mais núcleos ou uso intensivo da CPU e comparar com as ferramentas do sistema por favor me de um feedback
E quem rir da qualidade do meu inglês nos comentários eu vou banir o ip!
#!/usr/bin/env python import time import os # [ reference ] # Detect number of cpus # http://www.boduch.ca/2009/06/python-cpus.html # Get cpu usage (But this example is not working 100%) # http://ubuntuforums.org/showpost.php?p=853257&postcount=4 INTERVAL = 2 class CPUUsage: def __init__(self): self.cores = self.detectCPUs() def createCoreArray(self): cores = [] for i in range(self.cores): cores.append("") return cores def detectCPUs(self): if hasattr(os, "sysconf"): if os.sysconf_names.has_key("SC_NPROCESSORS_ONLN"): ncpus = os.sysconf("SC_NPROCESSORS_ONLN") if isinstance(ncpus, int) and ncpus > 0: return ncpus return 1 # Default def getTimeList(self): core = self.createCoreArray() statFile = file("/proc/stat", "r") if not self.cores == 1: statFile.readline() # this FOR will split lines from proc/stat for every active core for cid in range(self.cores): # when have just one core, split a different range if self.cores == 1: core[cid] = statFile.readline().split(" ")[2:7] # 2:6 else: core[cid] = statFile.readline().split(" ")[1:6] # 1:5 statFile.close() # convert all itens in splited list from STR to INT for every core for i in range(len(core[0])): for cid in range(self.cores): core[cid][i] = int(core[cid][i]) # return the core list now with INT values inside their cpu values # like this: ([core,1,values],[core,2,values],[core,3,values]) return core def deltaTime(self,interval): coreT1=self.createCoreArray() coreT2=self.createCoreArray() # get core TIME 1 state per core coreT1 = self.getTimeList() # wait X seconds to get new state core time.sleep(interval) # get core TIME 2 state per core coreT2 = self.getTimeList() #Get the diference of coreT2.item[i] and coreT1.item[i] for every core for i in range(len(coreT1[0])): for cid in range(self.cores): coreT2[cid][i] -= coreT1[cid][i] return coreT2 def Usage(self): core = self.createCoreArray() cpuUsage = [] core = self.deltaTime(INTERVAL) for cid in range(self.cores): # sum of user,system and nice usage tmp_use = core[cid][0] + core[cid][1]+core[cid][2] # 100.00 * usage / sum of usage + idle + waiting usage = "%.2f" % ((100.00 * tmp_use) / sum(core[cid])) cpuUsage.append(usage) return cpuUsage if __name__ == "__main__": # Show usage per core #print CPUUsage().Usage() x = 0 for item in CPUUsage().Usage(): x = x + 1 print "CPU[%s]: %s" % (str(x),str(item)) |
Na tarde de sábado eu precisava pegar as portas abertas no servidor, da forma mais Real Time possível. Primeira idéia? Naturalmente, foi parsear o resultado do netstat e ‘grepar’ o LISTEN ou OUÇA, mas depois imaginei que beber diretamente da fonte pudesse fazer o negócio andar mais rápido. Pesquisa daqui, pesquisa dali, aparentemente o netstat pega suas informações dos arquivos em /proc/net.
Após umas horinhas consegui o protótipo inicial do código que preciso. Mas durante a caminhada perdi o foco e acabei brincando um pouco mais com o /proc/net/tcp, no fim tinha um netstat simplificado feito em Python.
Então se alguém algum dia precisar recuperar informações de conexões ao estilo netstat aí está o código:
#!/usr/bin/python # Criado por Ricardo Pascal, qualquer dúvida ou # contribuição mande para 'pascal.linux' no gmail! # Pode usar a vontade só lembre-se de citar a autoria ;) # Agradecimento ao pessoal do #python-br na freenode. # A galera lá sempre ajuda. PROC_TCP = "/proc/net/tcp" STATE = { '01':'ESTABLISHED', '02':'SYN_SENT', '03':'SYN_RECV', '04':'FIN_WAIT1', '05':'FIN_WAIT2', '06':'TIME_WAIT', '07':'CLOSE', '08':'CLOSE_WAIT', '09':'LAST_ACK', '0A':'LISTEN', '0B':'CLOSING' } tcp_FH = open(PROC_TCP,'r') content = tcp_FH.readlines() content.pop(0) # remove header tcp_FH.close() def hex2dec(s): return int(s,16) def ip(s): return str(hex2dec(s[6:8])) +"."+ str(hex2dec(s[4:6])) +"."+ \ str(hex2dec(s[2:4])) +"."+ str(hex2dec(s[0:2])) def remove_empty(list): return [x for x in list if x !=''] def get_list(c): result = [] result.append(['ID','IP','PORT','rIP','rPORT','STATS']) for lines in content: line_array = remove_empty(lines.split(' ')) line = [line_array[0], line_array[1].split(':'), \ line_array[2].split(":"),line_array[3]] line = [line[0], ip(line[1][0]), hex2dec(line[1][1]), \ ip(line[2][0]), hex2dec(line[2][1]), STATE[(line[3])]] result.append(line) return result if __name__ == '__main__': for lines in get_list(content): print lines |
PS. Quando eu tiver tempo eu refaço a cama de gato que ta ali na função get_list() e ip().
- SimpleHTTPServer
- BaseHTTPServer
- wsgi
- WebOb
- Aspen
- PEP:333
- Olha que legal, basicamente o meu problema!!
- Static (Olha que legal, basicamente resolve o meu problema!!)
- Albatross
- Spyce
- CherryPY e/ou StandaloneWSGI Server
Imagino que no final vou acabar usando o Standalone WSGI Server (engine do CherryPy) com a solução apresentada no Static. Mas até lá continuo fazendo meus testes com o CherryPy mesmo.
Alguma vez enquanto você escrevia um código já aconteceu de “acidentalmente” soltar um rm * no lugar errado? Pois é, comigo já. Aconteceu ALGUMAS vezes, teve até um dia que isso aconteceu DUAS vezes, e lá vai o tanso aqui reescrever todo o código.
Alguns podem dizer que a melhor maneira de evitar isso é usar um repositório versionado. Mas e se você quer apenas escrever um script? Não precisa nem ser “bonito”, basta funcionar? Nesses casos o uso de um repositório parece que só te atrasa.
Pensando nisso (e usando a filosofia do não precisa nem ser bonito, basta funcionar), criei esse fim de semana o backup_this. Basicamente é uma ferramenta que comprime a pasta corrente em um arquivo .tar.gz e envia ela para o gmail.
Funciona assim:

Se você quiser testar pode fazer o download aqui, depois é só mover para /usr/bin/ e colocar a permissão de execução.
Eu estou gostando, acho que até que vou fazer umas melhorias. Incluir envio por ssh, exclusão de tipos de arquivos, passagem de alvos como parâmetros e etecétera.
Eu não gosto muito de trabalhar com servidores de e-mail, na sua maioria são caóticos em se tratando do gerenciamento. Tudo que você quer fazer depende de muitas modificações nos arquivos de configuração, adição de patches ou softwares extras. Particularmente me desagrada muito a maneira como se linka os mail servers a um banco de dados para gerenciar usuários e domínios. Mas aparentemente não sou o único a pensar assim.
Duncan McGreggor levou isso ao próximo nível, o cara codificou o próprio mail server. Infelizmente ele parou com a “loucura” mas felizmente ele disponibilizou o código no launchpad.
Estive pensando em dar uma olhada, e quem sabe, trabalhar em cima do código, ou talvez eu deva fazer o meu próprio? Com certeza traria um bocado de conhecimento e muitas horas de diversão!
E você? Já teve vontade de reescrever um software por não gostar dos já disponíveis na comunidade?
Acontece que naquele momento eu não dispunha de internet ou bons materiais sobre Python(exceto o help) para suportar o processo de criação do código, de tal modo que aproveitei a situação para medir a quantas andava o meu conhecimento sobre Python.
Então, usando apenas o conhecimento disponível na minha cabeça eu comecei a escrever o código e após alguns minutos de tentativa e erros cheguei ao seguinte resultado:
#!/usr/bin/python import random def rand_op(): return random.randint(0,1) def rand_number(): return random.randint(0,9) def rand_letter(): alpha = [ 'a','b','c','d','e','f','g','h','i','j','k','l','n','o','p','q','r','s','t','u','v','x','z','w','y' ] return random.choice(alpha) def generate (size): final = '' for x in range(size): y = rand_op() #print y if y == 0: value = rand_number() if y == 1: value = rand_letter() op = random.randint(0,1) if op == 0: pass if op == 1: value = value.upper() final = final + str(value) print final for k in range(20): generate(10) |
#!/usr/bin/python import string import random def genPass(lenght): AlphaNumeric = string.ascii_letters + string.digits PassWord = ''.join([random.choice(AlphaNumeric) for _ in range(lenght)]) return PassWord for _ in range(10): print genPass(12) |
- o conceito de list comprehensions
- novos métodos do módulo string
É eu sei… aprender é divertido!
- são 300.000 usuários cadastrados
- suporta até 40.000 usuários concorrentes(conectados ao mesmo tempo)
- Stackless Python é usado tanto no servidor quanto no cliente.
- o banco de dados usado é o SQL Server da microsoft
- o cluster de banco de dados roda sobre SSD
Ainda segundo o texto, os discos SSD ajudam MUITO no desempenho do sistema. Assim que eles ficarem mais acessíveis eu compro um para testes.
Se você já quis um arquivo de configuração para fazer um programa/script ter uma cara mais profissional, eis aqui uma solução simples em python. Read the rest of this entry »

