Changelog History
Page 1
-
v22.1.0 Changes
July 20, 2022โ Removed
- ๐ Python 3.6 is not supported anymore.
- Pickling is now only possible with protocol version 3 and newer.
๐ Deprecated
- ๐ The entire
structlog.threadlocal
module is deprecated. Please use the primitives fromstructlog.contextvars
instead.
If you're using the modern APIs (
bind_threadlocal()
/merge_threadlocal()
) it's enough to replace them 1:1 with theircontextvars
counterparts. The old approach aroundwrap_dict()
has been discouraged for a while.Currently there are no concrete plans to remove the module, but no patches against it will be accepted from now on. #409
โ Added
- โ
structlog.processors.StackInfoRenderer
now has an additional_ignores parameter that allows you to filter out your own logging layer. #396 - โ Added
structlog.WriteLogger
, a faster โ but more low-level โ alternative tostructlog.PrintLogger
. It works the wayPrintLogger
used to work in previous versions. #403 #404 structlog.make_filtering_bound_logger()
-returned loggers now also have alog()
method to match thestructlog.stdlib.BoundLogger
signature closer. #413- โ Added structured logging of tracebacks via the
structlog.tracebacks
module, and most notably thestructlog.tracebacks.ExceptionDictTransformer
which can be used with the newstructlog.processors.ExceptionRenderer
to render JSON tracebacks. #407 - 0๏ธโฃ
structlog.stdlib.recreate_defaults(log_level=logging.NOTSET)
that recreatesstructlog
's defaults on top of standard library'slogging
. It optionally also configureslogging
to log to standard out at the passed log level. #428 structlog.processors.EventRenamer
allows you to rename the hitherto hard-coded event dict keyevent
to something else. Optionally, you can rename another key toevent
at the same time, too. So addingEventRenamer(to="msg", replace_by="_event")
to your processor pipeline will rename the standardevent
key tomsg
and then rename the_event
key toevent
. This allows you to use theevent
key in your own log files and to have consistent log message keys across languages.- ๐ฒ
structlog.dev.ConsoleRenderer(event_key="event")
now allows to customize the name of the key that is used for the log message.
๐ Changed
structlog.make_filtering_bound_logger()
now returns a method with the same signature for all log levels, whether they are active or not. This ensures that invalid calls to inactive log levels are caught immediately and don't explode once the log level changes. #401- 0๏ธโฃ
structlog.PrintLogger
โ that is used by default โ now usesprint()
for printing, making it a better citizen for interactive terminal applications. #399 - โ
structlog.testing.capture_logs
now works for already initialized bound loggers. #408 structlog.processors.format_exc_info()
is no longer a function, but an instance ofstructlog.processors.ExceptionRenderer
. Its behavior has not changed. #407- ๐ง The default configuration now includes the
structlog.contextvars.merge_contextvars
processor. That means you can usestructlog.contextvars
features without configuringstructlog
.
๐ Fixed
- ๐ Overloaded the
bind
,unbind
,try_unbind
andnew
methods in theFilteringBoundLogger
Protocol. This makes it easier to use objects of typeFilteringBoundLogger
in a typed context. #392 - 0๏ธโฃ Monkeypatched
sys.stdout
s are now handled more gracefully byConsoleRenderer
(that's used by default). #404 structlog.stdlib.render_to_log_kwargs()
now correctly handles the presence ofexc_info
,stack_info
, andstackLevel
in the event dictionary. They are transformed into proper keyword arguments instead of putting them into theextra
dictionary. #424, #427
-
v21.5.0 Changes
December 16, 2021Backward-incompatible changes:
none
๐ Deprecations: ^
none
๐ Changes: ^
- โ Added the
structlog.processors.LogfmtRenderer
processor to render log lines using thelogfmt <https://brandur.org/logfmt>
_ format.#376 <https://github.com/hynek/structlog/pull/376>
_ - โ Added the
structlog.stdlib.ExtraAdder
processor that adds extra attributes oflogging.LogRecord
objects to the event dictionary. This processor can be used for adding data passed in theextra
parameter of thelogging
module's log methods to the event dictionary.#209 <https://github.com/hynek/structlog/pull/209>
_#377 <https://github.com/hynek/structlog/pull/377>
_ - โ Added the
structlog.processor.CallsiteParameterAdder
processor that adds parameters of the callsite that an event dictionary orginated from to the event dictionary. This processor can be used to enrich events dictionaries with information such as the function name, line number and filename that an event dictionary orignated from.#380 <https://github.com/hynek/structlog/pull/380>
_
- โ Added the
-
v21.4.0 Changes
November 25, 2021Backward-incompatible changes:
none
๐ Deprecations: ^
none
๐ Changes: ^
- ๐ Fixed import when running in optimized mode (
PYTHONOPTIMIZE=2
orpython -OO
).#373 <https://github.com/hynek/structlog/pull/373>
_ - Added the
structlog.threadlocal.bound_threadlocal
andstructlog.contextvars.bound_contextvars
decorator/context managers to temporarily bind key/value pairs to a thread-local and context-local context.#371 <https://github.com/hynek/structlog/pull/371>
_
- ๐ Fixed import when running in optimized mode (
-
v21.3.0 Changes
November 20, 2021Backward-incompatible changes:
structlog
switched its packaging toflit <https://flit.readthedocs.io/>
_. Users shouldn't notice a difference, but (re-)packagers might.
๐ Deprecations: ^
none
๐ Changes: ^
structlog.dev.ConsoleRenderer
now hassort_keys
boolean parameter that allows to disable the sorting of keys on output.#358 <https://github.com/hynek/structlog/pull/358>
_- ๐ง
structlog.processors.TimeStamper
now works well with FreezeGun even when it gets applied before the loggers are configured.#364 <https://github.com/hynek/structlog/pull/364>
_ - ๐ฒ
structlog.stdlib.AsyncBoundLogger
now determines the running loop when logging, not on instantiation. That has a minor performance impact, but makes it more robust when loops change (e.g.aiohttp.web.run_app()
), or you want to usesync_bl
before a loop has started. - ๐จ
structlog.stdlib.ProcessorFormatter
now has a processors argument that allows to define a processor chain to run over all log entries.
Before running the chain, two additional keys are added to the event dictionary:
_record
and_from_structlog
. With them it's possible to extract information fromlogging.LogRecord
\s and differentiate betweenstructlog
andlogging
log entries while processing them.The old processor (singular) parameter is now deprecated, but no plans exist to remove it.
#365 <https://github.com/hynek/structlog/pull/365>
_
-
v21.2.0 Changes
October 12, 2021Backward-incompatible changes:
- ๐ To implement pretty exceptions (see Changes below),
structlog.dev.ConsoleRenderer
now formats exceptions itself.
Make sure to remove
format_exc_info
from your processor chain if you configurestructlog
manually. This change is not really breaking, because the old use-case will keep working as before. However if you passpretty_exceptions=True
(which is the default if eitherrich
orbetter-exceptions
is installed), a warning will be raised and the exception will be renderered without prettyfication.๐ Deprecations: ^
none
๐ Changes: ^
structlog
is now importable ifsys.stdout
isNone
(e.g. when running usingpythonw
).#313 <https://github.com/hynek/structlog/issues/313>
_structlog.threadlocal.get_threadlocal()
andstructlog.contextvars.get_contextvars()
can now be used to get a copy of the current thread-local/context-local context that has been bound usingstructlog.threadlocal.bind_threadlocal()
andstructlog.contextvars.bind_contextvars()
.#331 <https://github.com/hynek/structlog/pull/331>
_#337 <https://github.com/hynek/structlog/pull/337>
_- ๐
structlog.threadlocal.get_merged_threadlocal(bl)
andstructlog.contextvars.get_merged_contextvars(bl)
do the same, but also merge the context from a bound logger bl. Same pull requests as previous change. structlog.contextvars.bind_contextvars()
now returns a mapping of keys tocontextvars.Token
\s, allowing you to reset values using the newstructlog.contextvars.reset_contextvars()
.#339 <https://github.com/hynek/structlog/pull/339>
_- ๐ง Exception rendering in
structlog.dev.ConsoleLogger
is now configurable using theexception_formatter
setting. If either therich <https://github.com/willmcgugan/rich>
_ or thebetter-exceptions <https://github.com/qix-/better-exceptions>
_ package is present,structlog
will use them for pretty-printing tracebacks.rich
takes precedence overbetter-exceptions
if both are present.
This only works if
format_exc_info
is absent in the processor chain.#330 <https://github.com/hynek/structlog/pull/330>
_#349 <https://github.com/hynek/structlog/pull/349>
_- ๐ All use of
colorama
on non-Windows systems has been excised. Thus, colors are now enabled by default instructlog.dev.ConsoleRenderer
on non-Windows systems. You can keep usingcolorama
to customize colors, of course.#345 <https://github.com/hynek/structlog/pull/345>
_ - The final processor can now return a
bytearray
(additionally tostr
andbytes
).#344 <https://github.com/hynek/structlog/issues/344>
_
- ๐ To implement pretty exceptions (see Changes below),
-
v21.1.0 Changes
February 18, 2021Backward-incompatible changes:
none
๐ Deprecations: ^
none
๐ Changes: ^
structlog.threadlocal.wrap_dict()
now has a correct type annotation.#290 <https://github.com/hynek/structlog/pull/290>
_- ๐ Fix isolation in
structlog.contextvars
.#302 <https://github.com/hynek/structlog/pull/302>
_ - ๐ง The default configuration and loggers are pickleable again.
#301 <https://github.com/hynek/structlog/pull/301>
_ structlog.dev.ConsoleRenderer
will now look for alogger_name
key if nologger
key is set.#295 <https://github.com/hynek/structlog/pull/295>
_
-
v20.2.0 Changes
December 31, 2020Backward-incompatible changes:
๐ Python 2.7 and 3.5 aren't supported anymore. The package meta data should ensure that you keep getting 20.1.0 on those versions.
#244 <https://github.com/hynek/structlog/pull/244>
_structlog
is now fully type-annotated. This won't break your applications, but if you use Mypy, it will most likely break your CI.
Check out the new chapter on typing for details.
- ๐ง The default bound logger (
wrapper_class
) if you don't configurestructlog
has changed. It's mostly compatible with the old one but a few uncommon methods likelog
,failure
, orerr
don't exist anymore.
You can regain the old behavior by using
structlog.configure(wrapper_class=structlog.BoundLogger)
.Please note that due to the various interactions between settings, it's possible that you encounter even more errors. We strongly urge you to always configure all possible settings since the default configuration is not covered by our
backward compatibility policy <https://www.structlog.org/en/stable/backward-compatibility.html>
_.๐ Deprecations: ^
- ๐ Accessing the
_context
attribute of a bound logger is now deprecated. Please use the newstructlog.get_context()
.
๐ Changes: ^
structlog
has now type hints for all of its APIs! Sincestructlog
is highly dynamic and configurable, this led to a few concessions like a specializedstructlog.stdlib.get_logger()
whose only difference tostructlog.get_logger()
is that it has the correct type hints.
We consider them provisional for the time being โ i.e. the backward compatibility does not apply to them in its full strength until we feel we got it right. Please feel free to provide feedback!
#223 <https://github.com/hynek/structlog/issues/223>
,#282 <https://github.com/hynek/structlog/issues/282>
- Added
structlog.make_filtering_logger
that can be used likeconfigure(wrapper_class=make_filtering_bound_logger(logging.INFO))
. It creates a highly optimized bound logger whose inactive methods only consist of areturn None
. This is now also the default logger. - ๐ฒ As a complement,
structlog.stdlib.add_log_level()
can now additionally be imported asstructlog.processors.add_log_level
since it just adds the method name to the event dict. - ๐ฒ
structlog.processors.add_log_level()
is now part of the default configuration. structlog.stdlib.ProcessorFormatter
no longer uses exceptions for control flow, allowingforeign_pre_chain
processors to usesys.exc_info()
to access the real exception.- โ Added
structlog.BytesLogger
to avoid unnecessary encoding round trips. Concretely this is useful with orjson which returns bytes.#271 <https://github.com/hynek/structlog/issues/271>
_ - The final processor now also may return bytes that are passed untouched to the wrapped logger.
structlog.get_context()
allows you to retrieve the original context of a bound logger.#266 <https://github.com/hynek/structlog/issues/266>
_,- ๐จ
structlog.PrintLogger
now supportscopy.deepcopy()
.#268 <https://github.com/hynek/structlog/issues/268>
_ - โ Added
structlog.testing.CapturingLogger
for more unit testing goodness. - โ Added
structlog.stdlib.AsyncBoundLogger
that executes logging calls in a thread executor and therefore doesn't block.#245 <https://github.com/hynek/structlog/pull/245>
_
-
v20.1.0 Changes
January 28, 2020Backward-incompatible changes:
none
๐ Deprecations: ^
- ๐ This is the last version to support Python 2.7 (including PyPy) and 3.5. All following versions will only support Python 3.6 or later.
๐ Changes: ^
- โ Added a new module
structlog.contextvars
that allows to have a global but context-localstructlog
context the same way as withstructlog.threadlocal
since 19.2.0.#201 <https://github.com/hynek/structlog/issues/201>
,#236 <https://github.com/hynek/structlog/pull/236>
- โ Added a new module
structlog.testing
for first class testing support. The first entry is the context managercapture_logs()
that allows to make assertions about structured log calls.#14 <https://github.com/hynek/structlog/issues/14>
,#234 <https://github.com/hynek/structlog/pull/234>
- โ Added
structlog.threadlocal.unbind_threadlocal()
.#239 <https://github.com/hynek/structlog/pull/239>
_ - The logger created by
structlog.get_logger()
is not detected as an abstract method anymore, when attached to an abstract base class.#229 <https://github.com/hynek/structlog/issues/229>
_ - ๐
colorama
isn't initialized lazily on Windows anymore because it breaks rendering.#232 <https://github.com/hynek/structlog/issues/232>
,#242 <https://github.com/hynek/structlog/pull/242>
-
v19.2.0 Changes
October 16, 2019Backward-incompatible changes:
- ๐ Python 3.4 is not supported anymore. It has been unsupported by the Python core team for a while now and its PyPI downloads are negligible.
It's very unlikely that
structlog
will break under 3.4 anytime soon, but we don't test it anymore.๐ Deprecations: ^
none
๐ Changes: ^
- ๐ Full Python 3.8 support for
structlog.stdlib
. - โ Added more pass-through properties to
structlog.stdlib.BoundLogger
. To makes it easier to use it as a drop-in replacement forlogging.Logger
.#198 <https://github.com/hynek/structlog/issues/198>
_ structlog.stdlib.ProcessorFormatter
now takes a logger object as an optional keyword argument. This makesProcessorFormatter
work properly withstuctlog.stdlib.filter_by_level()
.#219 <https://github.com/hynek/structlog/issues/219>
_- 0๏ธโฃ
structlog.dev.ConsoleRenderer
now uses no colors by default, ifcolorama
is not available.#215 <https://github.com/hynek/structlog/issues/215>
_ structlog.dev.ConsoleRenderer
now initializescolorama
lazily, to prevent accidental side-effects just by importingstructlog
.#210 <https://github.com/hynek/structlog/issues/210>
_- Added new processor
structlog.dev.set_exc_info()
that will setexc_info=True
if the method's name isexception
andexc_info
isn't set at all. This is only necessary when the standard library integration is not used. It fixes the problem that in the default configuration,structlog.get_logger().exception("hi")
in anexcept
block would not print the exception without passingexc_info=True
to it explicitly.#130 <https://github.com/hynek/structlog/issues/130>
,#173 <https://github.com/hynek/structlog/issues/173>
,#200 <https://github.com/hynek/structlog/issues/200>
,#204 <https://github.com/hynek/structlog/issues/204>
- A best effort has been made to make as much of
structlog
pickleable as possible to make it friendlier withmultiprocessing
and similar libraries. Some classes can only be pickled on Python 3 or using thedill <https://pypi.org/project/dill/>
_ library though and that is very unlikely to change.
So far, the configuration proxy,
structlog.processor.TimeStamper
,structlog.BoundLogger
,structlog.PrintLogger
andstructlog.dev.ConsoleRenderer
have been made pickelable. Please report if you need any another class fixed.#126 <https://github.com/hynek/structlog/issues/126>
_- โ Added a new thread-local API that allows binding values to a thread-local context explicitly without affecting the default behavior of
bind()
.#222 <https://github.com/hynek/structlog/issues/222>
,#225 <https://github.com/hynek/structlog/issues/225>
- Added
pass_foreign_args
argument tostructlog.stdlib.ProcessorFormatter
. It allows to pass a foreign log record'sargs
attribute to the event dictionary under thepositional_args
key.#228 <https://github.com/hynek/structlog/issues/228>
_ structlog.dev.ConsoleRenderer
now callsstr()
on the event value.#221 <https://github.com/hynek/structlog/issues/221>
_
-
v19.1.0 Changes
February 02, 2019Backward-incompatible changes:
- As announced in 18.1.0,
pip install -e .[dev]
now installs all development dependencies. Sorry for the inconveniences this undoubtedly will cause!
๐ Deprecations: ^
none
๐ Changes: ^
- ๐จ
structlog.ReturnLogger
andstructlog.PrintLogger
now have afatal()
log method.#181 <https://github.com/hynek/structlog/issues/181>
_ - ๐ป Under certain (rather unclear) circumstances, the frame extraction could throw an
SystemError: error return without exception set
. A workaround has been added.#174 <https://github.com/hynek/structlog/issues/174>
_ - ๐ฒ
structlog
now tolerates passing throughdict
\ s to stdlib logging.#187 <https://github.com/hynek/structlog/issues/187>
,#188 <https://github.com/hynek/structlog/pull/188>
,#189 <https://github.com/hynek/structlog/pull/189>
_
- As announced in 18.1.0,