Há algum tempo, vi um aplicativo Mono com saída colorida, provavelmente por causa de seu sistema de log (porque todas as mensagens foram padronizadas).
Agora, o Python possui o logging
módulo, que permite especificar muitas opções para personalizar a saída. Então, estou imaginando que algo semelhante seria possível com o Python, mas não consigo descobrir como fazer isso em nenhum lugar.
Existe alguma maneira de fazer a logging
saída do módulo Python em cores?
O que eu quero (por exemplo) erros em vermelho, mensagens de depuração em azul ou amarelo e assim por diante.
Obviamente, isso provavelmente exigiria um terminal compatível (a maioria dos terminais modernos é); mas eu poderia voltar à logging
saída original se a cor não for suportada.
Alguma idéia de como obter impressões coloridas com o módulo de registro?
Respostas:
Eu já sabia sobre as fugas de cores, usei-as no meu prompt do bash há um tempo. Obrigado mesmo assim.
O que eu queria era integrá-lo ao módulo de registro, o que finalmente fiz depois de algumas tentativas e erros.
Aqui está o que eu acabo com:
E para usá-lo, crie seu próprio Logger:
Apenas no caso de mais alguém precisar.
Tenha cuidado se estiver usando mais de um criador de logs ou manipulador:
ColoredFormatter
está alterando o objeto de registro, que é passado ainda mais para outros manipuladores ou propagado para outros criadores de logs. Se você configurou registradores de arquivos, etc., provavelmente não deseja ter as cores nos arquivos de log. Para evitar isso, provavelmente é melhor simplesmente criar uma cópia derecord
withcopy.copy()
antes de manipular o atributo levelname ou redefinir o levelname para o valor anterior, antes de retornar a string formatada (crédito para Michael nos comentários).fonte
Formatter
e especificar seu uso em aStreamHandler
. Mas não há necessidade de uma subclasse de logger. De fato, o uso de uma classe de criador de logs adiciona um manipulador a cada criador de logs criado, que não é o que você normalmente deseja.ColoredFormatter
. Ele está alterando o objeto de registro, que é passado adiante para outros manipuladores ou propagado para outros registradores. Se você configurou registradores de arquivos, etc., provavelmente não deseja ter as cores nos arquivos de log. Para evitar isso, provavelmente é melhor simplesmente criar uma cópia derecord
withcopy.copy()
antes de manipular o atributo levelname ou redefinir o nome do nível para o valor anterior, antes de retornar a sequência formatada.Anos atrás, escrevi um manipulador de fluxo colorido para meu próprio uso. Então me deparei com esta página e encontrei uma coleção de trechos de código que as pessoas estão copiando / colando :-(. Atualmente, meu manipulador de fluxo só funciona no UNIX (Linux, Mac OS X), mas a vantagem é que ele está disponível no PyPI (e no GitHub ) e é muito simples de usar.Também possui um modo de sintaxe Vim :-). No futuro, eu poderia estendê-lo para funcionar no Windows.
Para instalar o pacote:
Para confirmar que funciona:
Para começar com seu próprio código:
O formato de log padrão mostrado no exemplo acima contém a data, hora, nome do host, o nome do criador de logs, o PID, o nível do log e a mensagem de log. É assim na prática:
NOTA: Ao usar o Git Bash com MinTTY
O Git Bash no Windows possui algumas peculiaridades documentadas: Winpty e Git Bash
Para códigos de escape ANSI e para reescrições e animações de caracteres no estilo ncurses, é necessário prefixar comandos com
winpty
.fonte
AttributeError: 'module' object has no attribute 'install'
ao usarcoloredlogs.install()
. Você pode confirmar isso com a versão mais recente.logging.basicConfig()
ecoloredlogs.install()
instalar um manipulador de fluxo que os logs para o console, assim, sem "anular" que se obtém mensagens duplicadas ...coloredlogs.install
qual formato usar, como nocolorlog
pacote.Aqui está uma solução que deve funcionar em qualquer plataforma. Se isso não me disser, eu irei atualizá-lo.
Como funciona: na plataforma que suporta escapes ANSI, você as usa (não Windows) e, no Windows, usa chamadas de API para alterar as cores do console.
O script hackea o método logging.StreamHandler.emit da biblioteca padrão, adicionando um wrapper a ele.
TestColorer.py
Colorer.py
fonte
args[1].msg = color + str(args[1].msg) + '\x1b[0m' # normal
.TestColorer.py
me preocupa.Atualização : Como essa é uma coceira que pretendo coçar há tanto tempo, escrevi uma biblioteca para pessoas preguiçosas como eu que só querem maneiras simples de fazer as coisas: zenlog
O Colorlog é excelente para isso. Está disponível no PyPI (e, portanto, instalável
pip install colorlog
) e é mantido ativamente .Aqui está um trecho rápido de copiar e colar para configurar o log e imprimir mensagens de log com aparência decente:
Resultado:
fonte
setLevel
realmente necessário?)Solução rápida e suja para níveis de log predefinidos e sem definir uma nova classe.
fonte
logging.basicConfig(format='%(asctime)s [%(name)s] [%(levelname)s] %(message)s')
Onde%(levelnames)s
é claro que é importante.echo -e "Normal texst \033[1;31mred bold text\033[0m normal text again"
. A-e
opção echo interpreta "\ 033" como forma octal do símbolo Escape ASCII. Este símbolo especial faz com que alguns terminais compatíveis interpretem caracteres subseqüentes (m
inclusive char ) como comandos especiais. pt.wikipedia.org/wiki/ANSI_escape_codeif sys.sdterr.isatty():
. Nesse caso, se você redirecionar a saída para o arquivo, o arquivo não conterá esses caracteres de escape.Código 2020, nenhum pacote adicional necessário, Python 3
Definir uma classe
Instanciar logger
E use!
Resultado
O esquema de cores
Para Windows
Esta solução funciona no Mac OS, terminais IDE. Parece que o prompt de comando da janela não possui cores por padrão. Aqui estão as instruções sobre como ativá-los, que eu não tentei https://www.howtogeek.com/322432/how-to-customize-your-command-prompts-color-scheme-with-microsofts-colortool/
fonte
←[38;21m2019-11-12 19:29:50,994 - My_app - DEBUG - debug message (test_colored_log.py:43)←[0m ←[38;21m2019-11-12 19:29:50,994 - My_app - INFO - info message (test_colored_log.py:44)←[0m ←[33;21m2019-11-12 19:29:50,994 - My_app - WARNING - warning message (test_colored_log.py:45)←[0m ←[31;21m2019-11-12 19:29:50,994 - My_app - ERROR - error message (test_colored_log.py:46)←[0m ←[31;1m2019-11-12 19:29:50,994 - My_app - CRITICAL - critical message (test_colored_log.py:47)←[0m
Bem, acho que devo adicionar minha variação do logger colorido.
Isso não é nada chique, mas é muito simples de usar e não altera o objeto de registro, evitando assim o registro das seqüências de escape ANSI em um arquivo de log se um manipulador de arquivo for usado. Não afeta a formatação da mensagem de log.
Se você já estiver usando o Formatador do módulo de registro , tudo o que você precisa fazer para obter nomes de níveis coloridos é substituir o Formatador dos manipuladores de aconselhamento pelo ColoredFormatter. Se você estiver registrando um aplicativo inteiro, precisará fazer isso apenas para o criador de logs de nível superior.
colored_log.py
Exemplo de uso
app.py
sub_module.py
Resultados
Saída terminal
conteúdo app.log
É claro que você pode obter o que quiser com a formatação das saídas do terminal e do arquivo de log. Somente o nível do log será colorido.
Espero que alguém ache isso útil e não seja apenas o mesmo. :)
Os arquivos de exemplo do Python podem ser baixados neste GitHub Gist: https://gist.github.com/KurtJacobson/48e750701acec40c7161b5a2f79e6bfd
fonte
return
:colored_record.msg = ('{0}{1}m{2}{3}').format(self.PREFIX, seq, colored_record.getMessage(), self.SUFFIX)
Atualizei o exemplo das tags de suporte do airmind para primeiro e segundo plano. Basta usar as variáveis de cor $ BLACK - $ WHITE na string do formatador de log. Para definir o plano de fundo, use $ BG-BLACK - $ BG-WHITE.
Então agora você pode simplesmente fazer o seguinte no seu arquivo de configuração:
fonte
super
só se aplica a algumas versões antigas do Python, eu acho? Uma vez que esta resposta é a partir de 2010. Ele trabalhou muito bem para mim com Python 2.7Você pode importar o módulo colorlog e usá-lo
ColoredFormatter
para colorir mensagens de log.Exemplo
Caldeira para o módulo principal:
O código ativa apenas cores nas mensagens de log, se o módulo colorlog estiver instalado e se a saída for realmente para um terminal. Isso evita que sequências de escape sejam gravadas em um arquivo quando a saída do log é redirecionada.
Além disso, é configurado um esquema de cores personalizado que é mais adequado para terminais com fundo escuro.
Alguns exemplos de chamadas de log:
Resultado:
fonte
colorlog.basicConfig
vez delogging.basicConfig
que tem alguns bons padrõesVeja a seguinte solução. O manipulador de fluxo deve ser o responsável pela coloração; então, você tem a opção de colorir palavras em vez de apenas a linha inteira (com o Formatador).
http://plumberjack.blogspot.com/2010/12/colorizing-logging-output-in-terminals.html
fonte
Modifiquei o exemplo original fornecido por Sorin e subclasse StreamHandler para ColorizedConsoleHandler.
A desvantagem de sua solução é que ela modifica a mensagem e, como isso está modificando a mensagem de log real, outros manipuladores também receberão a mensagem modificada.
Isso resultou em arquivos de log com códigos de cores, no nosso caso, porque usamos vários registradores.
A classe abaixo funciona apenas em plataformas que suportam ansi, mas deve ser trivial adicionar os códigos de cores do Windows a ela.
fonte
Agora existe um módulo PyPi lançado para saída de log colorida personalizável:
https://pypi.python.org/pypi/rainbow_logging_handler/
e
https://github.com/laysakura/rainbow_logging_handler
Suporta Windows
Suporta Django
Cores personalizáveis
Como isso é distribuído como um ovo Python, é muito fácil de instalar para qualquer aplicativo Python.
fonte
Há toneladas de respostas. Mas ninguém está falando sobre decoradores. Então aqui está o meu.
Porque é muito mais simples.
Não há necessidade de importar nada, nem escrever nenhuma subclasse:
Isso define os erros em vermelho, as mensagens de depuração em azul e assim por diante. Como perguntado na pergunta.
Poderíamos até adaptar o wrapper a um
color
argumento para definir dinamicamente a cor da mensagem usandologger.debug("message", color=GREY)
EDIT: Então aqui está o decorador adaptado para definir cores em tempo de execução:
fonte
Outro remix menor da abordagem do airmind que mantém tudo em uma classe:
Para usar anexar o formatador a um manipulador, algo como:
fonte
Uma ferramenta simples, mas muito flexível, para colorir QUALQUER texto do terminal é ' colout '.
Onde qualquer texto na saída de 'myprocess' que corresponda ao grupo 1 da regex será colorido com cor1, grupo 2 com cor2, etc.
Por exemplo:
ou seja, o primeiro grupo regex (parens) corresponde à data inicial no arquivo de log, o segundo grupo corresponde a um nome de arquivo python, número de linha e nome de função, e o terceiro grupo corresponde à mensagem de log que vem depois disso. Também uso uma sequência paralela de 'negrito / normais', bem como a sequência de cores. Isso se parece com:
Observe que linhas ou partes de linhas que não correspondem a nenhuma da minha regex ainda são ecoadas, portanto, isso não é como 'grep --color' - nada é filtrado para fora da saída.
Obviamente, isso é flexível o suficiente para que você possa usá-lo com qualquer processo, não apenas com os arquivos de log finais. Normalmente, eu apenas preparo um novo regex rapidamente, sempre que quiser colorir alguma coisa. Por esse motivo, prefiro o colout a qualquer ferramenta personalizada para colorir arquivos de log, porque só preciso aprender uma ferramenta, independentemente do que estiver colorindo: registro, saída de teste, sintaxe destacando trechos de código no terminal etc.
Ele também evita realmente despejar códigos ANSI no próprio arquivo de log, o que IMHO é uma péssima idéia, porque isso quebrará coisas como grepping para padrões no arquivo de log, a menos que você lembre-se sempre de combinar os códigos ANSI em seu regex grep.
fonte
fonte
[9*m
códigos para as cores ANSI "brilhantes"! PS, sua última linha me preocupa um pouco, porque ainda não se sabe se o log fora de uma definição de função é seguro no Python .Aqui está a minha solução:
fonte
A parte com a qual tive problemas foi configurar o formatador corretamente:
E então para usar:
fonte
Enquanto as outras soluções parecem boas, elas têm alguns problemas. Alguns colorem as linhas inteiras que algumas vezes não são desejadas e outros omitem qualquer configuração que você possa ter todos juntos. A solução abaixo não afeta nada além da própria mensagem.
Código
Exemplo
Resultado
Como você vê, todo o resto ainda é produzido e permanece em sua cor inicial. Se você quiser alterar qualquer outra coisa além da mensagem, basta passar os códigos de cores
log_format
no exemplo.fonte
[17:01:36]:WARNING:this should be yellowthis should be yellow
ou uma linha completa sendo impressa duas vezes?7s:%(message)s
arquivolog_format
.Tenho dois envios a serem adicionados, um dos quais colore apenas a mensagem (ColoredFormatter) e outro colore a linha inteira (ColorizingStreamHandler). Isso também inclui mais códigos de cores ANSI do que as soluções anteriores.
Algum conteúdo foi obtido (com modificação) de: A postagem acima e http://plumberjack.blogspot.com/2010/12/colorizing-logging-output-in-terminals.html .
Colorir apenas a mensagem:
Coloriza toda a linha:
fonte
Só respondi o mesmo em uma pergunta semelhante: Python | alterar a cor do texto no shell
A ideia é usar a biblioteca clint . Com suporte para shells para MAC, Linux e Windows (CLI).
fonte
Este é um Enum que contém os códigos de cores:
Isso pode ser aplicado aos nomes de cada nível de log. Esteja ciente de que este é um truque monstruoso.
Observe que seu formatador de log deve incluir o nome do nível de log
por exemplo:
fonte
FriendlyLog é outra alternativa. Funciona com Python 2 e 3 em Linux, Windows e MacOS.
fonte
Que tal destacar também argumentos de mensagens de log com cores alternadas, além de colorir por nível? Eu escrevi recentemente um código simples para isso. Outra vantagem é que a chamada de log é feita com a formatação de chave do Python 3. (
"{}"
)Veja o código e os exemplos mais recentes aqui: https://github.com/davidohana/colargulog
Código de log de amostra:
Resultado:
Implementação:
fonte
Use pyfancy .
Exemplo:
fonte
logging
funcionalidade para usar uma biblioteca de cores separada.Apenas mais uma solução, com as cores do ZetaSyanthis:
chame uma vez de sua
__main__
função. Eu tenho algo assim lá:também verifica se a saída é um console; caso contrário, nenhuma cor será usada.
fonte
Uso
Logger("File Name").info("This shows green text")
fonte
A solução a seguir funciona apenas com python 3, mas para mim parece mais clara.
A idéia é usar a fábrica de registros de log para adicionar atributos 'coloridos' aos objetos de registro de log e depois usar esses atributos 'coloridos' no formato de log.
Você pode modificar facilmente este exemplo para criar outros atributos coloridos (fe message_c) e, em seguida, usar esses atributos para obter o texto colorido (apenas) onde desejar.
(truque útil que descobri recentemente: tenho um arquivo com logs de depuração coloridos e sempre que quero aumentar temporariamente o nível de log do meu aplicativo, apenas
tail -f
o arquivo de log em um terminal diferente e vejo os logs de depuração na tela sem alterar qualquer configuração e reiniciar o aplicativo )fonte
Esta é outra variante Python3 do exemplo de airmind. Eu queria alguns recursos específicos que não vi nos outros exemplos
Notas: Eu usei o colorama, mas você pode modificar isso para que não seja necessário. Também para o meu teste eu estava apenas correndo arquivo python por isso a minha classe é no módulo
__main__
Você teria que mudar(): __main__.ColoredFormatter
para o que seu módulo é.logging.yaml
main.py
resultado:
fonte