click-contrib / click-log Goto Github PK
View Code? Open in Web Editor NEWSimple and beautiful logging for click applications
Home Page: https://click-log.readthedocs.org/
License: MIT License
Simple and beautiful logging for click applications
Home Page: https://click-log.readthedocs.org/
License: MIT License
Hi, thanks for all your hard work on this.
This commit e26170d introduced a breaking change to the API. Is there a way that I can change my code to:
Hi @untitaker , I see that info
output is not colorful, there's some reason for that? Maybe I can do a PR to add support?
Thanks!
Only getting unformatted console output when I try this. I'll be happy to submit some updated docs if you can help me through this:D
`import click
import click_log
import logging
logger = logging.getLogger(name)
fh = logging.FileHandler(name + '.log')
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
fh.setFormatter(formatter)
logger.addHandler(fh)
click_log.basic_config(logger)
@click.command()
@click_log.simple_verbosity_option(default='DEBUG', metavar='LEVEL')
@click.option('--execution_mode', default='dry_run', help="mode: [dry_run/install/force]")
def main(execution_mode, phase, load_local_files):
logger.info("beginning with execution mode: " + execution_mode)`
In the documentation it says
The simple_verbosity_option() decorator adds a --verbosity option that takes a (case-insensitive) value of DEBUG, INFO, WARNING, ERROR, or CRITICAL, and calls setLevel on the given logger accordingly.
It would be nice to add that the default level is INFO.
Otherwise, a user has to dig through the source code to find: https://github.com/click-contrib/click-log/blob/master/click_log/options.py#L21
click_log 0.3.0 seems to be printing the log messages unformatted instead of formatting the string with the args passed to the logging statement.
example.py:
import logging
import click
import click_log
logging.getLogger().setLevel(logging.INFO)
logger = logging.getLogger(__name__)
click_log.basic_config()
@click.command()
def foo():
logger.info('foo: %s', 'bar')
if __name__ == "__main__":
foo()
With click_log<0.3, this results in
$ python example.py
foo: bar
With click_log==0.3, you get
$ python example.py
foo: %s
I use click-log
in my CLIs to provides color-coded messages depending on levels and it works great! But I also need to provide to my users a --no-color
option at the CLI level to strip all ANSI codes.
The way I actually do it consist in hacking my way to the ColorFormatter.colors
variable and reset all its color configuration. Here is my implementation: kdeldycke/meta-package-manager@d960f29
To make things future-proof and avoid hacking into click-log
implementation details, I'd like to have a sort of global parameter or a method to disable coloring entirely.
Hi. First of all, thank you for providing great OSS.
I think the short option -v
as --verbosity
is useful, but it is not documented. I think it should be.
If maintainers agree with it, I can create a PR for it.
I have a project with two module cli.py
and doit.py
.
In the main module cli.py
I use
log = logging.getLogger(__name__)
click_log.basic_config(log)
as suggest and the logging in this module is perfectly controllable via the command line.
However in the other module doit
the level of the logger is always set to WARNING
independent of the used command line option.
Hoe can I use click_log in the second module as well?
On an app with more than one logger, click_log will configure the logger for the initial module (where click_log.basic_config
is called), but not other modules.
This results in click_log
effectively having no effect on other modules.
A potential solution for this, would be to make basic_config
take logger
as an OPTIONAL parameter.
If logger == None
, then configure logging
(which basically means, override global defaults).
The log level is set once and for all in the option in the plugin.
That mean in a test suite that is playing with the log-level defaults, the level set within a previous test is carried upon the next. This happened to me in my project where I tested the effect of defaults loaded from the default_map
.
I found a way to fix this issue by resetting the log level after each CLI execution.
This fix should be merged upstream to this plugin. One way to properly does it is I guess to leverage the resource management utilities available in Click.
Hi there,
I'm a little new to click. I have a project structured this like this so far:
cli.py
api.py
cli.py is my main entrypoint:
from . import api
import click, click_log, logging
logger = logging.getLogger(__name__)
click_log.basic_config(logger)
def main():
cli.add_command(api.login)
cli(auto_envvar_prefix='TEST', obj={})
@click_log.simple_verbosity_option(logger)
@click.group()
@click.pass_context
def cli(ctx):
logger.debug("test 1")
Then I have command groups broken out per-file. api.py:
import click, click_log
import logging
logger = logging.getLogger(__name__)
click_log.basic_config(logger)
@click.command()
@click.pass_context
def login(ctx):
logger.debug("test 2")
And my output when running is:
$ ./test_cli.py -v DEBUG login
debug: test 1"
So the log level is only being set in the cli file. And using my ide debugger i can see that the log level in the other file is 0
.
How do I go about setting up a unified verbose flag for commands across multiple files?
Hi,
I think this (great) feature should be contributed to click rather than being an independent contribution.
The docs are not really verbose about how to use click_log.basic_config()
.
Most intuitive way would be for it to have the same usage as here.
I wanted it to show the __name__
I pass into logging.getLogger(__name__)
, and preserve color output.
I am using click-log with success but I cannot find a way to write the logger data to a file.
Is this possible?
Normally I'd do something similar:
logging.basicConfig(filename='logs.log',
filemode='w',
level=logging.INFO)
But this doesn't work if I use click_log.
Thanks!
is there a way to make it work with https://github.com/hynek/structlog from @hynek?
i am currently can't make it work with simple level configuration.
e1:
import structlog
import click_log
log = structlog.getLogger()
@click.command()
@click_log.simple_verbosity_option()
@click_log.init()
def main():
structlog.configure(logger_factory=structlog.stdlib.LoggerFactory())
log.debug('test', v=1)
this work, but it also log the selenium module which my program use.
is there a way to limit the logger to my program only?
e2: still log other module
import logging
import structlog
import click_log
log = structlog.getLogger()
@click.command()
@click_log.simple_verbosity_option()
@click_log.init()
def main():
logging.basicConfig(level=click_log.get_level())
structlog.configure(logger_factory=structlog.stdlib.LoggerFactory())
log.debug('test', v=1)
e3: the working version without click_log
import logging
import structlog
@click.command()
@click.option('-d', '--debug', is_flag=True, help="Enable debug.")
def main(debug):
if debug:
logging.basicConfig(level=logging.DEBUG)
else:
logging.basicConfig(level=logging.INFO)
structlog.configure_once(logger_factory=structlog.stdlib.LoggerFactory())
log = structlog.getLogger()
log.debug('test', v=1)
I think the default behavior of logging is to output to stderr. Perhaps this should do the same, or at least make it configurable.
For example, I have scripts which product JSON output which I like to pipe through jq
command. I can do this even with logging messages if I just use logging.basicConfig()
, but with this project it goes to stdout
and messes up my JSON
I wanted to add the datetime to the formatting string and couldn't find a good way to do so. Perhaps the init
decorator could take a formatter or a function to call instead of basic_config? Anyhow, I've worked around this with monkey patching:
logger = logging.getLogger('myLogger')
handler = click_log.ClickHandler()
formatter = click_log.ColorFormatter('%(asctime)s - %(message)s')
handler.setFormatter(formatter)
click_log.core._default_handler = handler
@click_log.simple_verbosity_option()
@click_log.init(logger)
def cli(args):
pass
Even this is suboptimal, as the level is forced to lowercase in the handler emit()
method.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.