Retire repo
This repo was created by accident, use deb-python-oslo.log instead. Needed-By: I1ac1a06931c8b6dd7c2e73620a0302c29e605f03 Change-Id: I81894aea69b9d09b0977039623c26781093a397a
This commit is contained in:
parent
8a3fdb3b39
commit
5ef6f8015d
@ -1,7 +0,0 @@
|
||||
[run]
|
||||
branch = True
|
||||
source = oslo_log
|
||||
omit = oslo_log/tests/*
|
||||
|
||||
[report]
|
||||
ignore_errors = True
|
55
.gitignore
vendored
55
.gitignore
vendored
@ -1,55 +0,0 @@
|
||||
*.py[cod]
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Packages
|
||||
*.egg*
|
||||
*.egg-info
|
||||
dist
|
||||
build
|
||||
eggs
|
||||
parts
|
||||
bin
|
||||
var
|
||||
sdist
|
||||
develop-eggs
|
||||
.installed.cfg
|
||||
lib
|
||||
lib64
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
.coverage*
|
||||
cover
|
||||
.tox
|
||||
nosetests.xml
|
||||
.testrepository
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
|
||||
# Mr Developer
|
||||
.mr.developer.cfg
|
||||
.project
|
||||
.pydevproject
|
||||
|
||||
# Complexity
|
||||
output/*.html
|
||||
output/*/index.html
|
||||
|
||||
# Sphinx
|
||||
doc/build
|
||||
|
||||
# pbr generates these
|
||||
AUTHORS
|
||||
ChangeLog
|
||||
|
||||
# Editors
|
||||
*~
|
||||
.*.swp
|
||||
|
||||
# Files created by releasenotes build
|
||||
releasenotes/build
|
@ -1,4 +0,0 @@
|
||||
[gerrit]
|
||||
host=review.openstack.org
|
||||
port=29418
|
||||
project=openstack/oslo.log.git
|
3
.mailmap
3
.mailmap
@ -1,3 +0,0 @@
|
||||
# Format is:
|
||||
# <preferred e-mail> <other e-mail 1>
|
||||
# <preferred e-mail> <other e-mail 2>
|
@ -1,7 +0,0 @@
|
||||
[DEFAULT]
|
||||
test_command=OS_STDOUT_CAPTURE=${OS_STDOUT_CAPTURE:-1} \
|
||||
OS_STDERR_CAPTURE=${OS_STDERR_CAPTURE:-1} \
|
||||
OS_TEST_TIMEOUT=${OS_TEST_TIMEOUT:-60} \
|
||||
${PYTHON:-python} -m subunit.run discover -t ./ ./oslo_log $LISTOPT $IDOPTION
|
||||
test_id_option=--load-list $IDFILE
|
||||
test_list_option=--list
|
@ -1,16 +0,0 @@
|
||||
If you would like to contribute to the development of OpenStack,
|
||||
you must follow the steps in this page:
|
||||
|
||||
http://docs.openstack.org/infra/manual/developers.html
|
||||
|
||||
Once those steps have been completed, changes to OpenStack
|
||||
should be submitted for review via the Gerrit tool, following
|
||||
the workflow documented at:
|
||||
|
||||
http://docs.openstack.org/infra/manual/developers.html#development-workflow
|
||||
|
||||
Pull requests submitted through GitHub will be ignored.
|
||||
|
||||
Bugs should be filed on Launchpad, not GitHub:
|
||||
|
||||
https://bugs.launchpad.net/oslo.log
|
@ -1,4 +0,0 @@
|
||||
oslo.log Style Commandments
|
||||
======================================================
|
||||
|
||||
Read the OpenStack Style Commandments http://docs.openstack.org/developer/hacking/
|
175
LICENSE
175
LICENSE
@ -1,175 +0,0 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
21
README.rst
21
README.rst
@ -1,21 +0,0 @@
|
||||
================================
|
||||
oslo.log -- Oslo Logging Library
|
||||
================================
|
||||
|
||||
.. image:: https://img.shields.io/pypi/v/oslo.log.svg
|
||||
:target: https://pypi.python.org/pypi/oslo.log/
|
||||
:alt: Latest Version
|
||||
|
||||
.. image:: https://img.shields.io/pypi/dm/oslo.log.svg
|
||||
:target: https://pypi.python.org/pypi/oslo.log/
|
||||
:alt: Downloads
|
||||
|
||||
The oslo.log (logging) configuration library provides standardized
|
||||
configuration for all openstack projects. It also provides custom
|
||||
formatters, handlers and support for context specific
|
||||
logging (like resource id's etc).
|
||||
|
||||
* Free software: Apache license
|
||||
* Documentation: http://docs.openstack.org/developer/oslo.log
|
||||
* Source: http://git.openstack.org/cgit/openstack/oslo.log
|
||||
* Bugs: http://bugs.launchpad.net/oslo.log
|
13
README.txt
Normal file
13
README.txt
Normal file
@ -0,0 +1,13 @@
|
||||
This project is no longer maintained.
|
||||
|
||||
The contents of this repository are still available in the Git
|
||||
source code management system. To see the contents of this
|
||||
repository before it reached its end of life, please check out the
|
||||
previous commit with "git checkout HEAD^1".
|
||||
|
||||
Use instead the project deb-python-oslo.log at
|
||||
http://git.openstack.org/cgit/openstack/deb-python-oslo.log .
|
||||
|
||||
For any further questions, please email
|
||||
openstack-dev@lists.openstack.org or join #openstack-dev on
|
||||
Freenode.
|
@ -1,9 +0,0 @@
|
||||
==================
|
||||
oslo_log.fixture
|
||||
==================
|
||||
|
||||
.. module:: oslo_log.fixture
|
||||
|
||||
.. autofunction:: oslo_log.fixture.get_logging_handle_error_fixture
|
||||
|
||||
.. autoclass:: oslo_log.fixture.SetLogLevel
|
@ -1,8 +0,0 @@
|
||||
=====================
|
||||
oslo_log.formatters
|
||||
=====================
|
||||
|
||||
.. automodule:: oslo_log.formatters
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
@ -1,8 +0,0 @@
|
||||
=====================
|
||||
oslo_log.handlers
|
||||
=====================
|
||||
|
||||
.. automodule:: oslo_log.handlers
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
@ -1,8 +0,0 @@
|
||||
==================
|
||||
oslo_log.helpers
|
||||
==================
|
||||
|
||||
.. automodule:: oslo_log.helpers
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
@ -1,12 +0,0 @@
|
||||
==============
|
||||
oslo_log.log
|
||||
==============
|
||||
|
||||
.. automodule:: oslo_log.log
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
.. seealso::
|
||||
|
||||
:doc:`../usage`
|
@ -1,6 +0,0 @@
|
||||
=======================
|
||||
oslo_log.versionutils
|
||||
=======================
|
||||
|
||||
.. automodule:: oslo_log.versionutils
|
||||
:members:
|
@ -1,12 +0,0 @@
|
||||
==================
|
||||
oslo_log.watchers
|
||||
==================
|
||||
|
||||
.. automodule:: oslo_log.watchers
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
.. seealso::
|
||||
|
||||
:doc:`../usage`
|
@ -1,77 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
sys.path.insert(0, os.path.abspath('../..'))
|
||||
# -- General configuration ----------------------------------------------------
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be
|
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
|
||||
extensions = [
|
||||
'sphinx.ext.autodoc',
|
||||
'sphinx.ext.doctest',
|
||||
#'sphinx.ext.intersphinx',
|
||||
'oslosphinx',
|
||||
'oslo_config.sphinxext',
|
||||
]
|
||||
|
||||
# autodoc generation is a bit aggressive and a nuisance when doing heavy
|
||||
# text edit cycles.
|
||||
# execute "export SPHINX_DEBUG=1" in your terminal to disable
|
||||
|
||||
# The suffix of source filenames.
|
||||
source_suffix = '.rst'
|
||||
|
||||
# The master toctree document.
|
||||
master_doc = 'index'
|
||||
|
||||
# General information about the project.
|
||||
project = u'oslo.log'
|
||||
copyright = u'2014, OpenStack Foundation'
|
||||
|
||||
# If true, '()' will be appended to :func: etc. cross-reference text.
|
||||
add_function_parentheses = True
|
||||
|
||||
# If true, the current module name will be prepended to all description
|
||||
# unit titles (such as .. function::).
|
||||
add_module_names = True
|
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use.
|
||||
pygments_style = 'sphinx'
|
||||
|
||||
# -- Options for HTML output --------------------------------------------------
|
||||
|
||||
# The theme to use for HTML and HTML Help pages. Major themes that come with
|
||||
# Sphinx are currently 'default' and 'sphinxdoc'.
|
||||
# html_theme_path = ["."]
|
||||
# html_theme = '_theme'
|
||||
# html_static_path = ['static']
|
||||
|
||||
# Output file base name for HTML help builder.
|
||||
htmlhelp_basename = '%sdoc' % project
|
||||
|
||||
# Grouping the document tree into LaTeX files. List of tuples
|
||||
# (source start file, target name, title, author, documentclass
|
||||
# [howto/manual]).
|
||||
latex_documents = [
|
||||
('index',
|
||||
'%s.tex' % project,
|
||||
u'%s Documentation' % project,
|
||||
u'OpenStack Foundation', 'manual'),
|
||||
]
|
||||
|
||||
# Example configuration for intersphinx: refer to the Python standard library.
|
||||
#intersphinx_mapping = {'http://docs.python.org/': None}
|
@ -1,84 +0,0 @@
|
||||
=========================================
|
||||
Example Configuration File for ``nova``
|
||||
=========================================
|
||||
|
||||
This sample configuration file demonstrates how the OpenStack compute
|
||||
service (nova) might be configured.
|
||||
|
||||
.. literalinclude:: nova_sample.conf
|
||||
:language: ini
|
||||
:prepend: # nova_sample.conf
|
||||
|
||||
Two logger nodes are set up, ``root`` and ``nova``.
|
||||
|
||||
.. literalinclude:: nova_sample.conf
|
||||
:language: ini
|
||||
:lines: 1-2
|
||||
|
||||
Several handlers are created, to send messages to different outputs.
|
||||
|
||||
.. literalinclude:: nova_sample.conf
|
||||
:language: ini
|
||||
:lines: 4-5
|
||||
|
||||
And two formatters are created to be used based on whether the logging
|
||||
location will have OpenStack request context information available or
|
||||
not.
|
||||
|
||||
.. literalinclude:: nova_sample.conf
|
||||
:language: ini
|
||||
:lines: 7-8
|
||||
|
||||
The ``root`` logger is configured to send messages to the ``null``
|
||||
handler, silencing most messages that are not part of the nova
|
||||
application code namespace.
|
||||
|
||||
.. literalinclude:: nova_sample.conf
|
||||
:language: ini
|
||||
:lines: 10-12
|
||||
|
||||
The ``nova`` logger is configured to send messages marked as ``INFO``
|
||||
and higher level to the standard error stream.
|
||||
|
||||
.. literalinclude:: nova_sample.conf
|
||||
:language: ini
|
||||
:lines: 14-17
|
||||
|
||||
The ``amqp`` and ``amqplib`` loggers, used by the module that connects
|
||||
the application to the message bus, are configured to emit warning
|
||||
messages to the standard error stream.
|
||||
|
||||
.. literalinclude:: nova_sample.conf
|
||||
:language: ini
|
||||
:lines: 19-27
|
||||
|
||||
The ``sqlalchemy`` logger, used by the module that connects the
|
||||
application to the database, is configured to emit warning messages to
|
||||
the standard error stream.
|
||||
|
||||
.. literalinclude:: nova_sample.conf
|
||||
:language: ini
|
||||
:lines: 29-35
|
||||
|
||||
Similarly, ``boto``, ``suds``, and ``eventlet.wsgi.server`` are
|
||||
configured to send warnings to the standard error stream.
|
||||
|
||||
.. literalinclude:: nova_sample.conf
|
||||
:language: ini
|
||||
:lines: 37-53
|
||||
|
||||
The ``stderr`` handler, being used by most of the loggers above, is
|
||||
configured to write to the standard error stream on the console.
|
||||
|
||||
.. literalinclude:: nova_sample.conf
|
||||
:language: ini
|
||||
:lines: 55-58
|
||||
|
||||
The ``stderr`` handler uses the ``context`` formatter, which takes its
|
||||
configuration settings from ``oslo.config``.
|
||||
|
||||
.. literalinclude:: nova_sample.conf
|
||||
:language: ini
|
||||
:lines: 80-81
|
||||
|
||||
The ``stdout`` and ``syslog`` handlers are defined, but not used.
|
@ -1,47 +0,0 @@
|
||||
==============================
|
||||
Advanced Configuration Files
|
||||
==============================
|
||||
|
||||
The oslo.config options described in :doc:`/opts` make it easy to
|
||||
enable some default logging configuration behavior such as setting the
|
||||
default log level and output file. For more advanced configurations
|
||||
using translations or multiple output destinations oslo.log relies on
|
||||
the Python standard library logging module configuration file
|
||||
features.
|
||||
|
||||
The configuration file can be used to tie together the loggers,
|
||||
handlers, and formatters and provide all of the necessary
|
||||
configuration values to enable any desired behavior. Refer to the
|
||||
`Python logging Module Tutorial`_ for descriptions of these concepts.
|
||||
|
||||
Logger Names
|
||||
============
|
||||
|
||||
Loggers are configured by name. Most OpenStack applications use logger
|
||||
names based on the source file where the message is coming from. A
|
||||
file named ``myapp/package/module.py`` corresponds to a logger named
|
||||
``myapp.package.module``.
|
||||
|
||||
Loggers are configured in a tree structure, and the names reflect
|
||||
their location in this hierarchy. It is not necessary to configure
|
||||
every logger, since messages are passed up the tree during
|
||||
processing. To control the logging for ``myapp``, for example, it is
|
||||
only necessary to set up a logger for ``myapp`` and not
|
||||
``myapp.package.module``.
|
||||
|
||||
The base of the tree, through which all log message may pass unless
|
||||
otherwise discarded, is called the ``root`` logger.
|
||||
|
||||
Example Files
|
||||
=============
|
||||
|
||||
.. toctree::
|
||||
:glob:
|
||||
|
||||
example*
|
||||
|
||||
.. seealso::
|
||||
|
||||
* `Python logging Module Tutorial`_
|
||||
|
||||
.. _Python logging Module Tutorial: https://docs.python.org/2.7/howto/logging.html
|
@ -1,84 +0,0 @@
|
||||
[loggers]
|
||||
keys = root, nova
|
||||
|
||||
[handlers]
|
||||
keys = stderr, stdout, watchedfile, syslog, null
|
||||
|
||||
[formatters]
|
||||
keys = context, default
|
||||
|
||||
[logger_root]
|
||||
level = WARNING
|
||||
handlers = null
|
||||
|
||||
[logger_nova]
|
||||
level = INFO
|
||||
handlers = stderr
|
||||
qualname = nova
|
||||
|
||||
[logger_amqp]
|
||||
level = WARNING
|
||||
handlers = stderr
|
||||
qualname = amqp
|
||||
|
||||
[logger_amqplib]
|
||||
level = WARNING
|
||||
handlers = stderr
|
||||
qualname = amqplib
|
||||
|
||||
[logger_sqlalchemy]
|
||||
level = WARNING
|
||||
handlers = stderr
|
||||
qualname = sqlalchemy
|
||||
# "level = INFO" logs SQL queries.
|
||||
# "level = DEBUG" logs SQL queries and results.
|
||||
# "level = WARNING" logs neither. (Recommended for production systems.)
|
||||
|
||||
[logger_boto]
|
||||
level = WARNING
|
||||
handlers = stderr
|
||||
qualname = boto
|
||||
|
||||
# NOTE(mikal): suds is used by the vmware driver, removing this will
|
||||
# cause many extraneous log lines for their tempest runs. Refer to
|
||||
# https://review.openstack.org/#/c/219225/ for details.
|
||||
[logger_suds]
|
||||
level = INFO
|
||||
handlers = stderr
|
||||
qualname = suds
|
||||
|
||||
[logger_eventletwsgi]
|
||||
level = WARNING
|
||||
handlers = stderr
|
||||
qualname = eventlet.wsgi.server
|
||||
|
||||
[handler_stderr]
|
||||
class = StreamHandler
|
||||
args = (sys.stderr,)
|
||||
formatter = context
|
||||
|
||||
[handler_stdout]
|
||||
class = StreamHandler
|
||||
args = (sys.stdout,)
|
||||
formatter = context
|
||||
|
||||
[handler_watchedfile]
|
||||
class = handlers.WatchedFileHandler
|
||||
args = ('nova.log',)
|
||||
formatter = context
|
||||
|
||||
[handler_syslog]
|
||||
class = handlers.SysLogHandler
|
||||
args = ('/dev/log', handlers.SysLogHandler.LOG_USER)
|
||||
formatter = context
|
||||
|
||||
[handler_null]
|
||||
class = logging.NullHandler
|
||||
formatter = default
|
||||
args = ()
|
||||
|
||||
[formatter_context]
|
||||
class = oslo_log.formatters.ContextFormatter
|
||||
|
||||
[formatter_default]
|
||||
format = %(message)s
|
@ -1,5 +0,0 @@
|
||||
============
|
||||
Contributing
|
||||
============
|
||||
|
||||
.. include:: ../../CONTRIBUTING.rst
|
@ -1,60 +0,0 @@
|
||||
==========
|
||||
Examples
|
||||
==========
|
||||
|
||||
.. _examples:
|
||||
|
||||
These files can be found in the docs/source/examples directory of
|
||||
the git source of this project. They can also be found at the
|
||||
`online git respository`_ of this project.
|
||||
|
||||
.. _online git respository: http://git.openstack.org/cgit/openstack/oslo.log/tree/doc/source/examples
|
||||
|
||||
|
||||
python_logging.py
|
||||
-----------------
|
||||
|
||||
.. _example_python_logging.py:
|
||||
|
||||
.. highlight:: python
|
||||
.. literalinclude:: examples/python_logging.py
|
||||
:linenos:
|
||||
|
||||
oslo_logging.py
|
||||
---------------
|
||||
|
||||
.. _example_oslo_logging.py:
|
||||
|
||||
.. literalinclude:: examples/oslo_logging.py
|
||||
|
||||
usage.py
|
||||
--------
|
||||
|
||||
.. _example_usage.py:
|
||||
|
||||
.. literalinclude:: examples/usage.py
|
||||
:linenos:
|
||||
|
||||
usage_helper.py
|
||||
---------------
|
||||
|
||||
.. _example_usage_helper.py:
|
||||
|
||||
.. literalinclude:: examples/usage_helper.py
|
||||
:linenos:
|
||||
|
||||
usage_i18n.py
|
||||
-------------
|
||||
|
||||
.. _example_usage_i18n.py:
|
||||
|
||||
.. literalinclude:: examples/usage_i18n.py
|
||||
:linenos:
|
||||
|
||||
usage_context.py
|
||||
----------------
|
||||
|
||||
.. _example_usage_context.py:
|
||||
|
||||
.. literalinclude:: examples/usage_context.py
|
||||
:linenos:
|
@ -1,49 +0,0 @@
|
||||
# Copyright (c) 2016 OpenStack Foundation
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
"""A demonstration of oslo.i18n integration module that is used
|
||||
in projects wanting to implement Oslo i18n translation.
|
||||
|
||||
See http://docs.openstack.org/developer/oslo.i18n/usage.html
|
||||
"""
|
||||
|
||||
import oslo_i18n
|
||||
|
||||
DOMAIN = "demo"
|
||||
|
||||
_translators = oslo_i18n.TranslatorFactory(domain=DOMAIN)
|
||||
|
||||
# The primary translation function using the well-known name "_"
|
||||
_ = _translators.primary
|
||||
|
||||
# The contextual translation function using the name "_C"
|
||||
_C = _translators.contextual_form
|
||||
|
||||
# The plural translation function using the name "_P"
|
||||
_P = _translators.plural_form
|
||||
|
||||
# Translators for log levels.
|
||||
#
|
||||
# The abbreviated names are meant to reflect the usual use of a short
|
||||
# name like '_'. The "L" is for "log" and the other letter comes from
|
||||
# the level.
|
||||
_LI = _translators.log_info
|
||||
_LW = _translators.log_warning
|
||||
_LE = _translators.log_error
|
||||
_LC = _translators.log_critical
|
||||
|
||||
|
||||
def get_available_languages():
|
||||
return oslo_i18n.get_available_languages(DOMAIN)
|
@ -1,30 +0,0 @@
|
||||
# Copyright (c) 2016 OpenStack Foundation
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
"""A minimal syntax example of Oslo Logging"""
|
||||
|
||||
from oslo_config import cfg
|
||||
from oslo_log import log as logging
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
CONF = cfg.CONF
|
||||
DOMAIN = "demo"
|
||||
|
||||
logging.register_options(CONF)
|
||||
logging.setup(CONF, DOMAIN)
|
||||
|
||||
# Oslo Logging uses INFO as default
|
||||
LOG.info("Oslo Logging")
|
||||
LOG.warning("Oslo Logging")
|
||||
LOG.error("Oslo Logging")
|
@ -1,26 +0,0 @@
|
||||
# Copyright (c) 2016 OpenStack Foundation
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
"""A syntax example of Python Logging"""
|
||||
|
||||
import logging
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
# Define a default handler at INFO logging level
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
|
||||
LOG.info("Python Standard Logging")
|
||||
LOG.warning("Python Standard Logging")
|
||||
LOG.error("Python Standard Logging")
|
@ -1,86 +0,0 @@
|
||||
# Copyright (c) 2016 OpenStack Foundation
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
"""A usage example of Oslo Logging
|
||||
|
||||
This example requires the following package to be installed.
|
||||
|
||||
$ pip install oslo.log
|
||||
|
||||
Additional Oslo packages installed include oslo.config, oslo.context,
|
||||
oslo.i18n, osli.serialization and oslo.utils.
|
||||
|
||||
More information about Oslo Logging can be found at:
|
||||
|
||||
http://docs.openstack.org/developer/oslo.log/usage.html
|
||||
"""
|
||||
|
||||
from oslo_config import cfg
|
||||
from oslo_log import log as logging
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
CONF = cfg.CONF
|
||||
DOMAIN = 'demo'
|
||||
|
||||
|
||||
def prepare():
|
||||
"""Prepare Oslo Logging (2 or 3 steps)
|
||||
|
||||
Use of Oslo Logging involves the following:
|
||||
|
||||
* logging.register_options
|
||||
* logging.set_defaults (optional)
|
||||
* logging.setup
|
||||
"""
|
||||
|
||||
# Required step to register common, logging and generic configuration
|
||||
# variables
|
||||
logging.register_options(CONF)
|
||||
|
||||
# Optional step to set new defaults if necessary for
|
||||
# * logging_context_format_string
|
||||
# * default_log_levels
|
||||
#
|
||||
# These variables default to respectively:
|
||||
#
|
||||
# import oslo_log
|
||||
# oslo_log._options.DEFAULT_LOG_LEVELS
|
||||
# oslo_log._options.log_opts[0].default
|
||||
#
|
||||
|
||||
extra_log_level_defaults = [
|
||||
'dogpile=INFO',
|
||||
'routes=INFO'
|
||||
]
|
||||
|
||||
logging.set_defaults(
|
||||
default_log_levels=logging.get_default_log_levels() +
|
||||
extra_log_level_defaults)
|
||||
|
||||
# Required setup based on configuration and domain
|
||||
logging.setup(CONF, DOMAIN)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
prepare()
|
||||
# NOTE: These examples do not demonstration Oslo i18n messages
|
||||
|
||||
LOG.info("Welcome to Oslo Logging")
|
||||
LOG.debug("A debugging message")
|
||||
LOG.warning("A warning occurred")
|
||||
LOG.error("An error occurred")
|
||||
try:
|
||||
raise Exception("This is exceptional")
|
||||
except Exception:
|
||||
LOG.exception("An Exception occurred")
|
@ -1,85 +0,0 @@
|
||||
# Copyright (c) 2016 OpenStack Foundation
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
"""A usage example of Oslo Logging with context
|
||||
|
||||
This example requires the following package to be installed.
|
||||
|
||||
$ pip install oslo.log
|
||||
|
||||
Additional Oslo packages installed include oslo.config, oslo.context,
|
||||
oslo.i18n, osli.serialization and oslo.utils.
|
||||
|
||||
More information about Oslo Logging can be found at:
|
||||
|
||||
http://docs.openstack.org/developer/oslo.log/usage.html
|
||||
http://docs.openstack.org/developer/oslo.context/usage.html
|
||||
"""
|
||||
|
||||
from oslo_config import cfg
|
||||
from oslo_context import context
|
||||
from oslo_log import log as logging
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
CONF = cfg.CONF
|
||||
DOMAIN = 'demo'
|
||||
|
||||
|
||||
def prepare():
|
||||
"""Prepare Oslo Logging (2 or 3 steps)
|
||||
|
||||
Use of Oslo Logging involves the following:
|
||||
|
||||
* logging.register_options
|
||||
* logging.set_defaults (optional)
|
||||
* logging.setup
|
||||
"""
|
||||
|
||||
# Required step to register common, logging and generic configuration
|
||||
# variables
|
||||
logging.register_options(CONF)
|
||||
|
||||
# Optional step to set new defaults if necessary for
|
||||
# * logging_context_format_string
|
||||
# * default_log_levels
|
||||
#
|
||||
# These variables default to respectively:
|
||||
#
|
||||
# import oslo_log
|
||||
# oslo_log._options.DEFAULT_LOG_LEVELS
|
||||
# oslo_log._options.log_opts[0].default
|
||||
#
|
||||
|
||||
extra_log_level_defaults = [
|
||||
'dogpile=INFO',
|
||||
'routes=INFO'
|
||||
]
|
||||
|
||||
logging.set_defaults(
|
||||
default_log_levels=logging.get_default_log_levels() +
|
||||
extra_log_level_defaults)
|
||||
|
||||
# Required setup based on configuration and domain
|
||||
logging.setup(CONF, DOMAIN)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
prepare()
|
||||
|
||||
LOG.info("Welcome to Oslo Logging")
|
||||
LOG.info("Without context")
|
||||
context.RequestContext(user='6ce90b4d',
|
||||
tenant='d6134462',
|
||||
domain='a6b9360e')
|
||||
LOG.info("With context")
|
@ -1,103 +0,0 @@
|
||||
# Copyright (c) 2016 OpenStack Foundation
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
"""A usage example with helper debugging of minimum Oslo Logging
|
||||
|
||||
This example requires the following package to be installed.
|
||||
|
||||
$ pip install oslo.log
|
||||
|
||||
Additional Oslo packages installed include oslo.config, oslo.context,
|
||||
oslo.i18n, osli.serialization and oslo.utils.
|
||||
|
||||
More information about Oslo Logging can be found at:
|
||||
|
||||
http://docs.openstack.org/developer/oslo.log/usage.html
|
||||
"""
|
||||
|
||||
# Use default Python logging to display running output
|
||||
import logging as py_logging
|
||||
from oslo_config import cfg
|
||||
from oslo_log import log as logging
|
||||
|
||||
|
||||
LOG = py_logging.getLogger(__name__)
|
||||
CONF = cfg.CONF
|
||||
DOMAIN = "demo"
|
||||
|
||||
|
||||
def prepare():
|
||||
"""Prepare Oslo Logging (2 or 3 steps)
|
||||
|
||||
Use of Oslo Logging involves the following:
|
||||
|
||||
* logging.register_options
|
||||
* logging.set_defaults (optional)
|
||||
* logging.setup
|
||||
"""
|
||||
|
||||
LOG.debug("Prepare Oslo Logging")
|
||||
|
||||
LOG.info("Size of configuration options before %d", len(CONF))
|
||||
|
||||
# Required step to register common, logging and generic configuration
|
||||
# variables
|
||||
logging.register_options(CONF)
|
||||
|
||||
LOG.info("Size of configuration options after %d", len(CONF))
|
||||
|
||||
# Optional step to set new defaults if necessary for
|
||||
# * logging_context_format_string
|
||||
# * default_log_levels
|
||||
#
|
||||
# These variables default to respectively:
|
||||
#
|
||||
# import oslo_log
|
||||
# oslo_log._options.DEFAULT_LOG_LEVELS
|
||||
# oslo_log._options.log_opts[0].default
|
||||
#
|
||||
|
||||
custom_log_level_defaults = logging.get_default_log_levels() + [
|
||||
'dogpile=INFO',
|
||||
'routes=INFO'
|
||||
]
|
||||
|
||||
logging.set_defaults(default_log_levels=custom_log_level_defaults)
|
||||
|
||||
# NOTE: We cannot show the contents of the CONF object
|
||||
# after register_options() because accessing this caches
|
||||
# the default_log_levels subsequently modified with set_defaults()
|
||||
LOG.info("List of Oslo Logging configuration options and current values")
|
||||
LOG.info("=" * 80)
|
||||
for c in CONF:
|
||||
LOG.info("%s = %s" % (c, CONF[c]))
|
||||
LOG.info("=" * 80)
|
||||
|
||||
# Required setup based on configuration and domain
|
||||
logging.setup(CONF, DOMAIN)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
py_logging.basicConfig(level=py_logging.DEBUG)
|
||||
|
||||
prepare()
|
||||
# NOTE: These examples do not demonstration Oslo i18n messages
|
||||
LOG.info("Welcome to Oslo Logging")
|
||||
LOG.debug("A debugging message")
|
||||
LOG.warning("A warning occurred")
|
||||
LOG.error("An error occurred")
|
||||
try:
|
||||
raise Exception("This is exceptional")
|
||||
except Exception:
|
||||
LOG.exception("An Exception occurred")
|
@ -1,87 +0,0 @@
|
||||
# Copyright (c) 2016 OpenStack Foundation
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
"""A usage example of Oslo Logging with Oslo i18n
|
||||
|
||||
This example requires the following package to be installed.
|
||||
$ pip install oslo.log
|
||||
|
||||
Additional Oslo packages installed include oslo.config, oslo.context,
|
||||
oslo.i18n, osli.serialization and oslo.utils.
|
||||
|
||||
More information about Oslo Logging can be found at:
|
||||
|
||||
http://docs.openstack.org/developer/oslo.log/usage.html
|
||||
http://docs.openstack.org/developer/oslo.i18n/usage.html
|
||||
"""
|
||||
|
||||
from oslo_config import cfg
|
||||
from oslo_log import log as logging
|
||||
from _i18n import _, _LI, _LW, _LE # noqa
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
CONF = cfg.CONF
|
||||
DOMAIN = 'demo'
|
||||
|
||||
|
||||
def prepare():
|
||||
"""Prepare Oslo Logging (2 or 3 steps)
|
||||
|
||||
Use of Oslo Logging involves the following:
|
||||
|
||||
* logging.register_options
|
||||
* logging.set_defaults (optional)
|
||||
* logging.setup
|
||||
"""
|
||||
|
||||
# Required step to register common, logging and generic configuration
|
||||
# variables
|
||||
logging.register_options(CONF)
|
||||
|
||||
# Optional step to set new defaults if necessary for
|
||||
# * logging_context_format_string
|
||||
# * default_log_levels
|
||||
#
|
||||
# These variables default to respectively:
|
||||
#
|
||||
# import oslo_log
|
||||
# oslo_log._options.DEFAULT_LOG_LEVELS
|
||||
# oslo_log._options.log_opts[0].default
|
||||
#
|
||||
|
||||
extra_log_level_defaults = [
|
||||
'dogpile=INFO',
|
||||
'routes=INFO'
|
||||
]
|
||||
|
||||
logging.set_defaults(
|
||||
default_log_levels=logging.get_default_log_levels() +
|
||||
extra_log_level_defaults)
|
||||
|
||||
# Required setup based on configuration and domain
|
||||
logging.setup(CONF, DOMAIN)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
prepare()
|
||||
# NOTE: These examples use Oslo i18n marker functions
|
||||
|
||||
LOG.info(_LI("Welcome to Oslo Logging"))
|
||||
LOG.debug("A debugging message") # Debug messages are not translated
|
||||
LOG.warning(_LW("A warning occurred"))
|
||||
LOG.error(_LE("An error occurred"))
|
||||
try:
|
||||
raise Exception(_("This is exceptional"))
|
||||
except Exception:
|
||||
LOG.exception(_LE("An Exception occurred"))
|
@ -1,7 +0,0 @@
|
||||
.. Add a fake link so that the reference to "assert_" in one of the
|
||||
changelog messages that looks like a reST link but isn't has
|
||||
something to resolve to.
|
||||
|
||||
.. _assert: https://docs.python.org/2/library/unittest.html#unittest.TestCase.assertTrue
|
||||
|
||||
.. include:: ../../ChangeLog
|
@ -1,36 +0,0 @@
|
||||
================================
|
||||
oslo.log -- Oslo Logging Library
|
||||
================================
|
||||
|
||||
The oslo.log (logging) configuration library provides standardized
|
||||
configuration for all openstack projects. It also provides custom
|
||||
formatters, handlers and support for context specific
|
||||
logging (like resource id's etc).
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
installation
|
||||
usage
|
||||
migration
|
||||
opts
|
||||
configfiles/index
|
||||
examples
|
||||
contributing
|
||||
history
|
||||
|
||||
API Documentation
|
||||
=================
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
:glob:
|
||||
|
||||
api/*
|
||||
|
||||
Indices and tables
|
||||
==================
|
||||
|
||||
* :ref:`genindex`
|
||||
* :ref:`modindex`
|
||||
* :ref:`search`
|
@ -1,12 +0,0 @@
|
||||
============
|
||||
Installation
|
||||
============
|
||||
|
||||
At the command line::
|
||||
|
||||
$ pip install oslo.log
|
||||
|
||||
To use ``oslo_log.fixture``, some additional dependencies
|
||||
are needed. They can be installed using the ``fixtures`` extra::
|
||||
|
||||
$ pip install 'oslo.log[fixtures]'
|
@ -1,119 +0,0 @@
|
||||
Migrating from Oslo Incubator to oslo.log
|
||||
=========================================
|
||||
|
||||
Applications using the incubated version of the logging code from Oslo
|
||||
may need to make some extra changes.
|
||||
|
||||
What do I import?
|
||||
-----------------
|
||||
|
||||
Our goal is to allow most libraries to import the Python standard
|
||||
library module, ``logging``, and not require ``oslo.log``
|
||||
directly. Applications may do the same, but if an application takes
|
||||
advantage of features like passing keywords through to the context for
|
||||
logging, it is likely to be less confusing to use ``oslo.log``
|
||||
everywhere, rather than have different types of loggers in different
|
||||
modules of the application.
|
||||
|
||||
No more ``audit()``
|
||||
-------------------
|
||||
|
||||
The ``audit()`` method of the old ``ContextAdapter`` class no longer
|
||||
exists. We agreed in the `cross project spec`_ to stop using audit
|
||||
level anyway, so those calls should be replaced with calls to
|
||||
``info()``.
|
||||
|
||||
.. _cross project spec: http://git.openstack.org/cgit/openstack/openstack-specs/tree/specs/log-guidelines.rst
|
||||
|
||||
Deprecation tools moved to ``versionutils``
|
||||
-------------------------------------------
|
||||
|
||||
The :meth:`deprecated` decorator and :class:`DeprecatedConfig` have
|
||||
moved to :mod:`oslo_log.versionutils`. Replace ``LOG.deprecated()``
|
||||
with :mod:`oslo_log.versionutils.report_deprecated_feature`, passing a
|
||||
local logger object as the first argument so the log message includes
|
||||
the location information.
|
||||
|
||||
No more implicit conversion to unicode/str
|
||||
------------------------------------------
|
||||
|
||||
The old :class:`ContextAdapter` used to convert anything given to it
|
||||
to a :class:`unicode` object before passing it to lower layers of the
|
||||
logging code. The new logging configuration uses a formatter instead
|
||||
of an adapter, so this conversion is no longer possible. All message
|
||||
format strings therefore need to be passed as unicode objects --
|
||||
that's strictly :class:`unicode`, not :class:`str`. If a message has
|
||||
no interpolation for extra parameters, a byte string can be used.
|
||||
|
||||
The most common place to encounter this is where :meth:`Logger.error`
|
||||
is used by passing an exception object as the first argument.
|
||||
|
||||
::
|
||||
|
||||
# Old style
|
||||
try:
|
||||
do_something()
|
||||
except Exception as err:
|
||||
LOG.error(err)
|
||||
|
||||
Now, the error should be converted to unicode either by calling
|
||||
:func:`six.text_type` or by using a unicode formatting string to
|
||||
provide context. It's even better to replace the redundant message
|
||||
produced by passing the exception with a useful message.
|
||||
|
||||
::
|
||||
|
||||
# New style, preferred approach
|
||||
from myapp._i18n import _LE # see oslo.i18n
|
||||
try:
|
||||
do_something()
|
||||
except Exception as err:
|
||||
LOG.exception(_LE(u"do_something couldn't do something"))
|
||||
|
||||
# New style, with exception
|
||||
from myapp._i18n import _LE # see oslo.i18n
|
||||
try:
|
||||
do_something()
|
||||
except Exception as err:
|
||||
LOG.error(_LE(u"do_something couldn't do something: %s"), err)
|
||||
|
||||
# New style, alternate without context
|
||||
import six
|
||||
try:
|
||||
do_something()
|
||||
except Exception as err:
|
||||
LOG.error(six.text_type(err))
|
||||
|
||||
Failure to do this for exceptions or other objects containing
|
||||
translatable strings from ``oslo.i18n`` results in an exception when
|
||||
the :class:`_Message` instance is combined in unsupported ways with
|
||||
the default formatting string inside the :mod:`logging` module in the
|
||||
standard library.
|
||||
|
||||
Changes to App Initialization
|
||||
-----------------------------
|
||||
|
||||
The logging options are no longer registered on the global
|
||||
configuration object defined in ``oslo.config``, and need to be
|
||||
registered explicitly on the configuration object being used by the
|
||||
application. Do this by calling :func:`~oslo_log.log.register_options`
|
||||
before parsing command line options.
|
||||
|
||||
The same configuration option passed to
|
||||
:func:`~oslo_log.log.register_options` should also be passed as the
|
||||
first argument to :func:`~oslo_log.log.setup`.
|
||||
|
||||
See :ref:`usage-app` for more details about application setup.
|
||||
|
||||
Passing Context
|
||||
---------------
|
||||
|
||||
Applications are expected to be using
|
||||
:class:`oslo_context.context.RequestContext` as the base class for
|
||||
their application-specific context classes. The base class manages a
|
||||
thread-local storage for the "current" context object so that
|
||||
``oslo.log`` can retrieve it without having the value passed in
|
||||
explicitly. This ensures that all log messages include the same
|
||||
context information, such as the request id and user
|
||||
identification. See the ``oslo.context`` documentation for details of
|
||||
using the class.
|
@ -1,9 +0,0 @@
|
||||
=======================
|
||||
Configuration Options
|
||||
=======================
|
||||
|
||||
oslo.log uses oslo.config to define and manage configuration options
|
||||
to allow the deployer to control how an application's logs are
|
||||
handled.
|
||||
|
||||
.. show-options:: oslo.log
|
@ -1,167 +0,0 @@
|
||||
=======
|
||||
Usage
|
||||
=======
|
||||
|
||||
.. _usage-app:
|
||||
|
||||
In an Application
|
||||
=================
|
||||
|
||||
When using `Python's standard logging library`_ the following minimal setup
|
||||
demostrates basic logging.
|
||||
|
||||
.. _Python's standard logging library: https://docs.python.org/2/library/logging.html
|
||||
|
||||
.. highlight:: python
|
||||
.. literalinclude:: examples/python_logging.py
|
||||
:linenos:
|
||||
:lines: 17-26
|
||||
|
||||
Source: :ref:`examples/python_logging.py <example_python_logging.py>`
|
||||
|
||||
When using Oslo Logging the following setup demonstrates a comparative
|
||||
syntax with Python standard logging.
|
||||
|
||||
|
||||
.. literalinclude:: examples/oslo_logging.py
|
||||
:linenos:
|
||||
:lines: 17-30
|
||||
:emphasize-lines: 8,9
|
||||
|
||||
Source: :ref:`examples/oslo_logging.py <example_oslo_logging.py>`
|
||||
|
||||
Oslo Logging Setup Methods
|
||||
--------------------------
|
||||
|
||||
Applications need to use the oslo.log configuration functions to register
|
||||
logging-related configuration options and configure the root and other
|
||||
default loggers before using standard logging functions.
|
||||
|
||||
Call :func:`~oslo_log.log.register_options` with an oslo.config CONF object
|
||||
before parsing any application command line options.
|
||||
|
||||
.. literalinclude:: examples/usage.py
|
||||
:linenos:
|
||||
:lines: 33,36-37,46-49
|
||||
:emphasize-lines: 7
|
||||
|
||||
Optionally call :func:`~oslo_log.log.set_defaults` before setup to
|
||||
change default logging levels if necessary.
|
||||
|
||||
.. literalinclude:: examples/usage.py
|
||||
:linenos:
|
||||
:lines: 51-53,61-69
|
||||
:emphasize-lines: 10
|
||||
|
||||
Call :func:`~oslo_log.log.setup` with the oslo.config CONF object used
|
||||
when registering objects, along with the domain and optionally a version
|
||||
to configure logging for the application.
|
||||
|
||||
.. literalinclude:: examples/usage.py
|
||||
:linenos:
|
||||
:lines: 34,36-37,70-72
|
||||
:emphasize-lines: 6
|
||||
|
||||
Source: :ref:`examples/usage.py <example_usage.py>`
|
||||
|
||||
Oslo Logging Functions
|
||||
----------------------
|
||||
|
||||
Use standard Python logging functions to produce log records at applicable
|
||||
log levels.
|
||||
|
||||
.. literalinclude:: examples/usage.py
|
||||
:linenos:
|
||||
:lines: 77-83
|
||||
|
||||
**Example Logging Output:**
|
||||
|
||||
::
|
||||
|
||||
2016-01-14 21:07:51.394 12945 INFO __main__ [-] Welcome to Oslo Logging
|
||||
2016-01-14 21:07:51.395 12945 WARNING __main__ [-] A warning occurred
|
||||
2016-01-14 21:07:51.395 12945 ERROR __main__ [-] An error occurred
|
||||
2016-01-14 21:07:51.396 12945 ERROR __main__ [-] An Exception occurred
|
||||
2016-01-14 21:07:51.396 12945 ERROR __main__ None
|
||||
2016-01-14 21:07:51.396 12945 ERROR __main__
|
||||
|
||||
Logging within an application should use `Oslo International Utilities (i18n)`_ marker
|
||||
functions to provide language translation capabilities.
|
||||
|
||||
.. _Oslo International Utilities (i18n): http://docs.openstack.org/developer/oslo.i18n/
|
||||
|
||||
.. literalinclude:: examples/usage_i18n.py
|
||||
:linenos:
|
||||
:lines: 31-32,76,79-85
|
||||
:emphasize-lines: 1
|
||||
|
||||
Source: :ref:`examples/usage_i18n.py <example_usage_i18n.py>`
|
||||
|
||||
With the use of `Oslo Context`_, log records can also contain
|
||||
additional contextual information applicable for your application.
|
||||
|
||||
.. _Oslo Context: http://docs.openstack.org/developer/oslo.context/
|
||||
|
||||
.. literalinclude:: examples/usage_context.py
|
||||
:linenos:
|
||||
:lines: 80-85
|
||||
:emphasize-lines: 3-5
|
||||
|
||||
**Example Logging Output:**
|
||||
|
||||
::
|
||||
|
||||
2016-01-14 20:04:34.562 11266 INFO __main__ [-] Welcome to Oslo Logging
|
||||
2016-01-14 20:04:34.563 11266 INFO __main__ [-] Without context
|
||||
2016-01-14 20:04:34.563 11266 INFO __main__ [req-bbc837a6-be80-4eb2-8ca3-53043a93b78d 6ce90b4d d6134462 a6b9360e - -] With context
|
||||
|
||||
The log record output format without context is defined with
|
||||
:oslo.config:option:`logging_default_format_string` configuration
|
||||
variable. When specifying context the
|
||||
:oslo.config:option:`logging_context_format_string` configuration
|
||||
variable is used.
|
||||
|
||||
The Oslo RequestContext object contains a number of attributes that can be
|
||||
specified in :oslo.config:option:`logging_context_format_string`. An
|
||||
application can extend this object to provide additional attributes that can
|
||||
be specified in log records.
|
||||
|
||||
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
:ref:`examples/usage.py <example_usage.py>` provides a documented
|
||||
example of Oslo Logging setup.
|
||||
|
||||
:ref:`examples/usage_helper.py <example_usage_helper.py>` provides an
|
||||
example showing debugging logging at each step details the configuration
|
||||
and logging at each step of Oslo Logging setup.
|
||||
|
||||
:ref:`examples/usage_i18n.py <example_usage_i18n.py>` provides a
|
||||
documented example of Oslo Logging with Oslo i18n supported messages.
|
||||
|
||||
:ref:`examples/usage_context.py <example_usage_context.py>` provides
|
||||
a documented example of Oslo Logging with Oslo Context.
|
||||
|
||||
|
||||
General Logging Guidelines
|
||||
==========================
|
||||
|
||||
The `OpenStack Logging Guidelines`_ in openstack-specs repository
|
||||
explain how to use different logging levels, and the desired logging
|
||||
patterns to be used in OpenStack applications.
|
||||
|
||||
.. _OpenStack Logging Guidelines: http://specs.openstack.org/openstack/openstack-specs/specs/log-guidelines.html
|
||||
|
||||
In a Library
|
||||
============
|
||||
|
||||
oslo.log is primarily used for configuring logging in an application,
|
||||
but it does include helpers that can be useful from libraries.
|
||||
|
||||
:func:`~oslo_log.log.getLogger` wraps the function of the same name
|
||||
from Python's standard library to add a
|
||||
:class:`~oslo_log.log.KeywordArgumentAdapter`, making it easier to
|
||||
pass data to the formatters provided by oslo.log and configured by an
|
||||
application.
|
@ -1,37 +0,0 @@
|
||||
# Copyright 2014 IBM Corp.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
"""oslo.i18n integration module.
|
||||
|
||||
See http://docs.openstack.org/developer/oslo.i18n/usage.html .
|
||||
|
||||
"""
|
||||
|
||||
import oslo_i18n
|
||||
|
||||
|
||||
_translators = oslo_i18n.TranslatorFactory(domain='oslo_log')
|
||||
|
||||
# The primary translation function using the well-known name "_"
|
||||
_ = _translators.primary
|
||||
|
||||
# Translators for log levels.
|
||||
#
|
||||
# The abbreviated names are meant to reflect the usual use of a short
|
||||
# name like '_'. The "L" is for "log" and the other letter comes from
|
||||
# the level.
|
||||
_LI = _translators.log_info
|
||||
_LW = _translators.log_warning
|
||||
_LE = _translators.log_error
|
||||
_LC = _translators.log_critical
|
@ -1,171 +0,0 @@
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from oslo_config import cfg
|
||||
|
||||
from oslo_log import versionutils
|
||||
|
||||
_DEFAULT_LOG_DATE_FORMAT = "%Y-%m-%d %H:%M:%S"
|
||||
|
||||
DEFAULT_LOG_LEVELS = ['amqp=WARN', 'amqplib=WARN', 'boto=WARN',
|
||||
'qpid=WARN', 'sqlalchemy=WARN', 'suds=INFO',
|
||||
'oslo.messaging=INFO', 'iso8601=WARN',
|
||||
'requests.packages.urllib3.connectionpool=WARN',
|
||||
'urllib3.connectionpool=WARN', 'websocket=WARN',
|
||||
'requests.packages.urllib3.util.retry=WARN',
|
||||
'urllib3.util.retry=WARN',
|
||||
'keystonemiddleware=WARN', 'routes.middleware=WARN',
|
||||
'stevedore=WARN', 'taskflow=WARN',
|
||||
'keystoneauth=WARN', 'oslo.cache=INFO',
|
||||
'dogpile.core.dogpile=INFO']
|
||||
|
||||
_IGNORE_MESSAGE = "This option is ignored if log_config_append is set."
|
||||
|
||||
common_cli_opts = [
|
||||
cfg.BoolOpt('debug',
|
||||
short='d',
|
||||
default=False,
|
||||
mutable=True,
|
||||
help='If set to true, the logging level will be set to '
|
||||
'DEBUG instead of the default INFO level.'),
|
||||
cfg.BoolOpt('verbose',
|
||||
short='v',
|
||||
default=True,
|
||||
help='If set to false, the logging level will be set to '
|
||||
'WARNING instead of the default INFO level.',
|
||||
deprecated_for_removal=True),
|
||||
]
|
||||
|
||||
logging_cli_opts = [
|
||||
cfg.StrOpt('log-config-append',
|
||||
metavar='PATH',
|
||||
deprecated_name='log-config',
|
||||
mutable=True,
|
||||
help='The name of a logging configuration file. This file '
|
||||
'is appended to any existing logging configuration '
|
||||
'files. For details about logging configuration files, '
|
||||
'see the Python logging module documentation. Note that '
|
||||
'when logging configuration files are used then all '
|
||||
'logging configuration is set in the configuration file '
|
||||
'and other logging configuration options are ignored '
|
||||
'(for example, logging_context_format_string).'),
|
||||
cfg.StrOpt('log-date-format',
|
||||
default=_DEFAULT_LOG_DATE_FORMAT,
|
||||
metavar='DATE_FORMAT',
|
||||
help='Defines the format string for %%(asctime)s in log '
|
||||
'records. Default: %(default)s . '
|
||||
+ _IGNORE_MESSAGE),
|
||||
cfg.StrOpt('log-file',
|
||||
metavar='PATH',
|
||||
deprecated_name='logfile',
|
||||
help='(Optional) Name of log file to send logging output to. '
|
||||
'If no default is set, logging will go to stderr as '
|
||||
'defined by use_stderr. '
|
||||
+ _IGNORE_MESSAGE),
|
||||
cfg.StrOpt('log-dir',
|
||||
deprecated_name='logdir',
|
||||
help='(Optional) The base directory used for relative log_file '
|
||||
' paths. '
|
||||
+ _IGNORE_MESSAGE),
|
||||
cfg.BoolOpt('watch-log-file',
|
||||
default=False,
|
||||
help='Uses logging handler designed to watch file '
|
||||
'system. When log file is moved or removed this handler '
|
||||
'will open a new log file with specified path '
|
||||
'instantaneously. It makes sense only if log_file option '
|
||||
'is specified and Linux platform is used. '
|
||||
+ _IGNORE_MESSAGE),
|
||||
cfg.BoolOpt('use-syslog',
|
||||
default=False,
|
||||
help='Use syslog for logging. '
|
||||
'Existing syslog format is DEPRECATED '
|
||||
'and will be changed later to honor RFC5424. '
|
||||
+ _IGNORE_MESSAGE),
|
||||
cfg.StrOpt('syslog-log-facility',
|
||||
default='LOG_USER',
|
||||
help='Syslog facility to receive log lines. '
|
||||
+ _IGNORE_MESSAGE),
|
||||
]
|
||||
|
||||
generic_log_opts = [
|
||||
cfg.BoolOpt('use_stderr',
|
||||
default=True,
|
||||
help='Log output to standard error. '
|
||||
+ _IGNORE_MESSAGE),
|
||||
]
|
||||
|
||||
log_opts = [
|
||||
cfg.StrOpt('logging_context_format_string',
|
||||
default='%(asctime)s.%(msecs)03d %(process)d %(levelname)s '
|
||||
'%(name)s [%(request_id)s %(user_identity)s] '
|
||||
'%(instance)s%(message)s',
|
||||
help='Format string to use for log messages with context.'),
|
||||
cfg.StrOpt('logging_default_format_string',
|
||||
default='%(asctime)s.%(msecs)03d %(process)d %(levelname)s '
|
||||
'%(name)s [-] %(instance)s%(message)s',
|
||||
help='Format string to use for log messages when context is '
|
||||
'undefined.'),
|
||||
cfg.StrOpt('logging_debug_format_suffix',
|
||||
default='%(funcName)s %(pathname)s:%(lineno)d',
|
||||
help='Additional data to append to log message when logging '
|
||||
'level for the message is DEBUG.'),
|
||||
cfg.StrOpt('logging_exception_prefix',
|
||||
default='%(asctime)s.%(msecs)03d %(process)d ERROR %(name)s '
|
||||
'%(instance)s',
|
||||
help='Prefix each line of exception output with this format.'),
|
||||
cfg.StrOpt('logging_user_identity_format',
|
||||
default='%(user)s %(tenant)s '
|
||||
'%(domain)s %(user_domain)s %(project_domain)s',
|
||||
help='Defines the format string for %(user_identity)s that '
|
||||
'is used in logging_context_format_string.'),
|
||||
cfg.ListOpt('default_log_levels',
|
||||
default=DEFAULT_LOG_LEVELS,
|
||||
help='List of package logging levels in logger=LEVEL pairs. '
|
||||
+ _IGNORE_MESSAGE),
|
||||
cfg.BoolOpt('publish_errors',
|
||||
default=False,
|
||||
help='Enables or disables publication of error events.'),
|
||||
|
||||
# NOTE(mikal): there are two options here because sometimes we are handed
|
||||
# a full instance (and could include more information), and other times we
|
||||
# are just handed a UUID for the instance.
|
||||
cfg.StrOpt('instance_format',
|
||||
default='[instance: %(uuid)s] ',
|
||||
help='The format for an instance that is passed with the log '
|
||||
'message.'),
|
||||
cfg.StrOpt('instance_uuid_format',
|
||||
default='[instance: %(uuid)s] ',
|
||||
help='The format for an instance UUID that is passed with the '
|
||||
'log message.'),
|
||||
]
|
||||
|
||||
|
||||
def list_opts():
|
||||
"""Returns a list of oslo.config options available in the library.
|
||||
|
||||
The returned list includes all oslo.config options which may be registered
|
||||
at runtime by the library.
|
||||
|
||||
Each element of the list is a tuple. The first element is the name of the
|
||||
group under which the list of elements in the second element will be
|
||||
registered. A group name of None corresponds to the [DEFAULT] group in
|
||||
config files.
|
||||
|
||||
The purpose of this is to allow tools like the Oslo sample config file
|
||||
generator (oslo-config-generator) to discover the options exposed to users
|
||||
by this library.
|
||||
|
||||
:returns: a list of (group_name, opts) tuples
|
||||
"""
|
||||
return [(None, (common_cli_opts + logging_cli_opts +
|
||||
generic_log_opts + log_opts +
|
||||
versionutils.deprecated_opts))]
|
@ -1,16 +0,0 @@
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from .logging_error import get_logging_handle_error_fixture
|
||||
from .setlevel import SetLogLevel
|
@ -1,37 +0,0 @@
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import fixtures
|
||||
|
||||
|
||||
def get_logging_handle_error_fixture():
|
||||
"""returns a fixture to make logging raise formatting exceptions.
|
||||
|
||||
To use::
|
||||
|
||||
from oslo_log import fixture as log_fixture
|
||||
|
||||
self.useFixture(log_fixture.get_logging_handle_error_fixture())
|
||||
"""
|
||||
return fixtures.MonkeyPatch('logging.Handler.handleError',
|
||||
_handleError)
|
||||
|
||||
|
||||
def _handleError(self, record):
|
||||
"""Monkey patch for logging.Handler.handleError.
|
||||
|
||||
The default handleError just logs the error to stderr but we want
|
||||
the option of actually raising an exception.
|
||||
"""
|
||||
raise
|
@ -1,49 +0,0 @@
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import logging
|
||||
|
||||
import fixtures
|
||||
|
||||
|
||||
class SetLogLevel(fixtures.Fixture):
|
||||
"""Override the log level for the named loggers, restoring their
|
||||
previous value at the end of the test.
|
||||
|
||||
To use::
|
||||
|
||||
from oslo_log import fixture as log_fixture
|
||||
|
||||
self.useFixture(log_fixture.SetLogLevel(['myapp.foo'], logging.DEBUG))
|
||||
|
||||
:param logger_names: Sequence of logger names, as would be passed
|
||||
to getLogger().
|
||||
:type logger_names: list(str)
|
||||
:param level: Logging level, usually one of logging.DEBUG,
|
||||
logging.INFO, etc.
|
||||
:type level: int
|
||||
"""
|
||||
|
||||
def __init__(self, logger_names, level):
|
||||
self.logger_names = logger_names
|
||||
self.level = level
|
||||
|
||||
def setUp(self):
|
||||
super(SetLogLevel, self).setUp()
|
||||
for name in self.logger_names:
|
||||
# NOTE(dhellmann): Use the stdlib version of getLogger()
|
||||
# so we get the logger and not any adaptor wrapping it.
|
||||
logger = logging.getLogger(name)
|
||||
self.addCleanup(logger.setLevel, logger.level)
|
||||
logger.setLevel(self.level)
|
@ -1,335 +0,0 @@
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import datetime
|
||||
import debtcollector
|
||||
import itertools
|
||||
import logging
|
||||
import logging.config
|
||||
import logging.handlers
|
||||
import socket
|
||||
import sys
|
||||
import traceback
|
||||
|
||||
from dateutil import tz
|
||||
import six
|
||||
from six import moves
|
||||
|
||||
from oslo_context import context as context_utils
|
||||
from oslo_serialization import jsonutils
|
||||
from oslo_utils import encodeutils
|
||||
|
||||
|
||||
def _dictify_context(context):
|
||||
if getattr(context, 'get_logging_values', None):
|
||||
return context.get_logging_values()
|
||||
elif getattr(context, 'to_dict', None):
|
||||
debtcollector.deprecate(
|
||||
'The RequestContext.get_logging_values() '
|
||||
'method should be defined for logging context specific '
|
||||
'information. The to_dict() method is deprecated '
|
||||
'for oslo.log use.', version='3.8.0', removal_version='5.0.0')
|
||||
return context.to_dict()
|
||||
# This dict only style logging format will become deprecated
|
||||
# when projects using a dictionary object for context are updated
|
||||
elif isinstance(context, dict):
|
||||
return context
|
||||
|
||||
return {}
|
||||
|
||||
|
||||
# A configuration object is given to us when the application registers
|
||||
# the logging options.
|
||||
_CONF = None
|
||||
|
||||
|
||||
def _store_global_conf(conf):
|
||||
global _CONF
|
||||
_CONF = conf
|
||||
|
||||
|
||||
def _update_record_with_context(record):
|
||||
"""Given a log record, update it with context information.
|
||||
|
||||
The request context, if there is one, will either be passed with the
|
||||
incoming record or in the global thread-local store.
|
||||
"""
|
||||
context = record.__dict__.get(
|
||||
'context',
|
||||
context_utils.get_current()
|
||||
)
|
||||
if context:
|
||||
d = _dictify_context(context)
|
||||
# Copy the context values directly onto the record so they can be
|
||||
# used by the formatting strings.
|
||||
for k, v in d.items():
|
||||
setattr(record, k, v)
|
||||
|
||||
return context
|
||||
|
||||
|
||||
def _ensure_unicode(msg):
|
||||
"""Do our best to turn the input argument into a unicode object.
|
||||
"""
|
||||
if isinstance(msg, six.text_type):
|
||||
return msg
|
||||
if not isinstance(msg, six.binary_type):
|
||||
return six.text_type(msg)
|
||||
return encodeutils.safe_decode(
|
||||
msg,
|
||||
incoming='utf-8',
|
||||
errors='xmlcharrefreplace')
|
||||
|
||||
|
||||
class _ReplaceFalseValue(dict):
|
||||
def __getitem__(self, key):
|
||||
return dict.get(self, key, None) or '-'
|
||||
|
||||
|
||||
class JSONFormatter(logging.Formatter):
|
||||
def __init__(self, fmt=None, datefmt=None):
|
||||
# NOTE(jkoelker) we ignore the fmt argument, but its still there
|
||||
# since logging.config.fileConfig passes it.
|
||||
self.datefmt = datefmt
|
||||
try:
|
||||
self.hostname = socket.gethostname()
|
||||
except socket.error:
|
||||
self.hostname = None
|
||||
|
||||
def formatException(self, ei, strip_newlines=True):
|
||||
lines = traceback.format_exception(*ei)
|
||||
if strip_newlines:
|
||||
lines = [moves.filter(
|
||||
lambda x: x,
|
||||
line.rstrip().splitlines()) for line in lines]
|
||||
lines = list(itertools.chain(*lines))
|
||||
return lines
|
||||
|
||||
def format(self, record):
|
||||
message = {'message': record.getMessage(),
|
||||
'asctime': self.formatTime(record, self.datefmt),
|
||||
'name': record.name,
|
||||
'msg': record.msg,
|
||||
'args': record.args,
|
||||
'levelname': record.levelname,
|
||||
'levelno': record.levelno,
|
||||
'pathname': record.pathname,
|
||||
'filename': record.filename,
|
||||
'module': record.module,
|
||||
'lineno': record.lineno,
|
||||
'funcname': record.funcName,
|
||||
'created': record.created,
|
||||
'msecs': record.msecs,
|
||||
'relative_created': record.relativeCreated,
|
||||
'thread': record.thread,
|
||||
'thread_name': record.threadName,
|
||||
'process_name': record.processName,
|
||||
'process': record.process,
|
||||
'traceback': None,
|
||||
'hostname': self.hostname}
|
||||
|
||||
# Build the extra values that were given to us, including
|
||||
# the context.
|
||||
context = _update_record_with_context(record)
|
||||
if hasattr(record, 'extra'):
|
||||
extra = record.extra.copy()
|
||||
else:
|
||||
extra = {}
|
||||
for key in getattr(record, 'extra_keys', []):
|
||||
if key not in extra:
|
||||
extra[key] = getattr(record, key)
|
||||
# If we saved a context object, explode it into the extra
|
||||
# dictionary because the values are more useful than the
|
||||
# object reference.
|
||||
if 'context' in extra:
|
||||
extra.update(_dictify_context(context))
|
||||
del extra['context']
|
||||
message['extra'] = extra
|
||||
|
||||
if record.exc_info:
|
||||
message['traceback'] = self.formatException(record.exc_info)
|
||||
|
||||
return jsonutils.dumps(message)
|
||||
|
||||
|
||||
class ContextFormatter(logging.Formatter):
|
||||
"""A context.RequestContext aware formatter configured through flags.
|
||||
|
||||
The flags used to set format strings are: logging_context_format_string
|
||||
and logging_default_format_string. You can also specify
|
||||
logging_debug_format_suffix to append extra formatting if the log level is
|
||||
debug.
|
||||
|
||||
The standard variables available to the formatter are listed at:
|
||||
http://docs.python.org/library/logging.html#formatter
|
||||
|
||||
In addition to the standard variables, one custom variable is
|
||||
available to both formatting string: `isotime` produces a
|
||||
timestamp in ISO8601 format, suitable for producing
|
||||
RFC5424-compliant log messages.
|
||||
|
||||
Furthermore, logging_context_format_string has access to all of
|
||||
the data in a dict representation of the context.
|
||||
"""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""Initialize ContextFormatter instance
|
||||
|
||||
Takes additional keyword arguments which can be used in the message
|
||||
format string.
|
||||
|
||||
:keyword project: project name
|
||||
:type project: string
|
||||
:keyword version: project version
|
||||
:type version: string
|
||||
|
||||
"""
|
||||
|
||||
self.project = kwargs.pop('project', 'unknown')
|
||||
self.version = kwargs.pop('version', 'unknown')
|
||||
self.conf = kwargs.pop('config', _CONF)
|
||||
|
||||
logging.Formatter.__init__(self, *args, **kwargs)
|
||||
|
||||
def format(self, record):
|
||||
"""Uses contextstring if request_id is set, otherwise default."""
|
||||
|
||||
if six.PY2:
|
||||
should_use_unicode = True
|
||||
for arg in record.args:
|
||||
try:
|
||||
six.text_type(arg)
|
||||
except UnicodeDecodeError:
|
||||
should_use_unicode = False
|
||||
break
|
||||
if (not isinstance(record.msg, six.text_type)
|
||||
and should_use_unicode):
|
||||
record.msg = _ensure_unicode(record.msg)
|
||||
|
||||
# store project info
|
||||
record.project = self.project
|
||||
record.version = self.version
|
||||
|
||||
# FIXME(dims): We need a better way to pick up the instance
|
||||
# or instance_uuid parameters from the kwargs from say
|
||||
# LOG.info or LOG.warn
|
||||
instance_extra = ''
|
||||
instance = getattr(record, 'instance', None)
|
||||
instance_uuid = getattr(record, 'instance_uuid', None)
|
||||
context = _update_record_with_context(record)
|
||||
if instance:
|
||||
try:
|
||||
instance_extra = (self.conf.instance_format
|
||||
% instance)
|
||||
except TypeError:
|
||||
instance_extra = instance
|
||||
elif instance_uuid:
|
||||
instance_extra = (self.conf.instance_uuid_format
|
||||
% {'uuid': instance_uuid})
|
||||
elif context:
|
||||
# FIXME(dhellmann): We should replace these nova-isms with
|
||||
# more generic handling in the Context class. See the
|
||||
# app-agnostic-logging-parameters blueprint.
|
||||
instance = getattr(context, 'instance', None)
|
||||
instance_uuid = getattr(context, 'instance_uuid', None)
|
||||
|
||||
# resource_uuid was introduced in oslo_context's
|
||||
# RequestContext
|
||||
resource_uuid = getattr(context, 'resource_uuid', None)
|
||||
|
||||
if instance:
|
||||
instance_extra = (self.conf.instance_format
|
||||
% {'uuid': instance})
|
||||
elif instance_uuid:
|
||||
instance_extra = (self.conf.instance_uuid_format
|
||||
% {'uuid': instance_uuid})
|
||||
elif resource_uuid:
|
||||
instance_extra = (self.conf.instance_uuid_format
|
||||
% {'uuid': resource_uuid})
|
||||
|
||||
record.instance = instance_extra
|
||||
|
||||
# NOTE(sdague): default the fancier formatting params
|
||||
# to an empty string so we don't throw an exception if
|
||||
# they get used
|
||||
for key in ('instance', 'color', 'user_identity', 'resource',
|
||||
'user_name', 'project_name'):
|
||||
if key not in record.__dict__:
|
||||
record.__dict__[key] = ''
|
||||
|
||||
# Set the "user_identity" value of "logging_context_format_string"
|
||||
# by using "logging_user_identity_format" and
|
||||
# get_logging_values of oslo.context.
|
||||
if context:
|
||||
record.user_identity = (
|
||||
self.conf.logging_user_identity_format %
|
||||
_ReplaceFalseValue(context.__dict__)
|
||||
)
|
||||
|
||||
if record.__dict__.get('request_id'):
|
||||
fmt = self.conf.logging_context_format_string
|
||||
else:
|
||||
fmt = self.conf.logging_default_format_string
|
||||
|
||||
if (record.levelno == logging.DEBUG and
|
||||
self.conf.logging_debug_format_suffix):
|
||||
fmt += " " + self.conf.logging_debug_format_suffix
|
||||
|
||||
self._compute_iso_time(record)
|
||||
|
||||
if sys.version_info < (3, 2):
|
||||
self._fmt = fmt
|
||||
else:
|
||||
self._style = logging.PercentStyle(fmt)
|
||||
self._fmt = self._style._fmt
|
||||
# Cache this on the record, Logger will respect our formatted copy
|
||||
if record.exc_info:
|
||||
record.exc_text = self.formatException(record.exc_info, record)
|
||||
return logging.Formatter.format(self, record)
|
||||
|
||||
def formatException(self, exc_info, record=None):
|
||||
"""Format exception output with CONF.logging_exception_prefix."""
|
||||
if not record:
|
||||
return logging.Formatter.formatException(self, exc_info)
|
||||
|
||||
stringbuffer = moves.StringIO()
|
||||
traceback.print_exception(exc_info[0], exc_info[1], exc_info[2],
|
||||
None, stringbuffer)
|
||||
lines = stringbuffer.getvalue().split('\n')
|
||||
stringbuffer.close()
|
||||
|
||||
if self.conf.logging_exception_prefix.find('%(asctime)') != -1:
|
||||
record.asctime = self.formatTime(record, self.datefmt)
|
||||
|
||||
self._compute_iso_time(record)
|
||||
|
||||
formatted_lines = []
|
||||
for line in lines:
|
||||
pl = self.conf.logging_exception_prefix % record.__dict__
|
||||
fl = '%s%s' % (pl, line)
|
||||
formatted_lines.append(fl)
|
||||
return '\n'.join(formatted_lines)
|
||||
|
||||
def _compute_iso_time(self, record):
|
||||
# set iso8601 timestamp
|
||||
localtz = tz.tzlocal()
|
||||
record.isotime = datetime.datetime.fromtimestamp(
|
||||
record.created).replace(tzinfo=localtz).isoformat()
|
||||
if record.created == int(record.created):
|
||||
# NOTE(stpierre): when the timestamp includes no
|
||||
# microseconds -- e.g., 1450274066.000000 -- then the
|
||||
# microseconds aren't included in the isoformat() time. As
|
||||
# a result, in literally one in a million cases
|
||||
# isoformat() looks different. This adds microseconds when
|
||||
# that happens.
|
||||
record.isotime = "%s.000000%s" % (record.isotime[:-6],
|
||||
record.isotime[-6:])
|
@ -1,76 +0,0 @@
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import inspect
|
||||
import logging
|
||||
import logging.config
|
||||
import logging.handlers
|
||||
import os
|
||||
try:
|
||||
import syslog
|
||||
except ImportError:
|
||||
syslog = None
|
||||
from oslo_utils import encodeutils
|
||||
|
||||
|
||||
NullHandler = logging.NullHandler
|
||||
|
||||
|
||||
def _get_binary_name():
|
||||
return os.path.basename(inspect.stack()[-1][1])
|
||||
|
||||
|
||||
_AUDIT = logging.INFO + 1
|
||||
_TRACE = 5
|
||||
|
||||
|
||||
if syslog is not None:
|
||||
class OSSysLogHandler(logging.Handler):
|
||||
"""Syslog based handler. Only available on UNIX-like platforms."""
|
||||
severity_map = {
|
||||
"CRITICAL": syslog.LOG_CRIT,
|
||||
"DEBUG": syslog.LOG_DEBUG,
|
||||
"ERROR": syslog.LOG_ERR,
|
||||
"INFO": syslog.LOG_INFO,
|
||||
"WARNING": syslog.LOG_WARNING,
|
||||
"WARN": syslog.LOG_WARNING,
|
||||
}
|
||||
|
||||
def __init__(self, facility=syslog.LOG_USER):
|
||||
# Do not use super() unless type(logging.Handler) is 'type'
|
||||
# (i.e. >= Python 2.7).
|
||||
logging.Handler.__init__(self)
|
||||
binary_name = _get_binary_name()
|
||||
syslog.openlog(binary_name, 0, facility)
|
||||
|
||||
def emit(self, record):
|
||||
priority = self.severity_map.get(record.levelname,
|
||||
syslog.LOG_DEBUG)
|
||||
message = encodeutils.safe_encode(self.format(record))
|
||||
|
||||
syslog.syslog(priority, message)
|
||||
|
||||
|
||||
class ColorHandler(logging.StreamHandler):
|
||||
LEVEL_COLORS = {
|
||||
_TRACE: '\033[00;35m', # MAGENTA
|
||||
logging.DEBUG: '\033[00;32m', # GREEN
|
||||
logging.INFO: '\033[00;36m', # CYAN
|
||||
_AUDIT: '\033[01;36m', # BOLD CYAN
|
||||
logging.WARN: '\033[01;33m', # BOLD YELLOW
|
||||
logging.ERROR: '\033[01;31m', # BOLD RED
|
||||
logging.CRITICAL: '\033[01;31m', # BOLD RED
|
||||
}
|
||||
|
||||
def format(self, record):
|
||||
record.color = self.LEVEL_COLORS[record.levelno]
|
||||
return logging.StreamHandler.format(self, record)
|
@ -1,49 +0,0 @@
|
||||
# Copyright (C) 2013 eNovance SAS <licensing@enovance.com>
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
"""Log helper functions."""
|
||||
|
||||
import functools
|
||||
import logging
|
||||
|
||||
|
||||
def _get_full_class_name(cls):
|
||||
return '%s.%s' % (cls.__module__,
|
||||
getattr(cls, '__qualname__', cls.__name__))
|
||||
|
||||
|
||||
def log_method_call(method):
|
||||
"""Decorator helping to log method calls.
|
||||
|
||||
:param method: Method to decorate to be logged.
|
||||
:type method: method definition
|
||||
"""
|
||||
log = logging.getLogger(method.__module__)
|
||||
|
||||
@functools.wraps(method)
|
||||
def wrapper(*args, **kwargs):
|
||||
if args:
|
||||
first_arg = args[0]
|
||||
cls = (first_arg if isinstance(first_arg, type)
|
||||
else first_arg.__class__)
|
||||
caller = _get_full_class_name(cls)
|
||||
else:
|
||||
caller = 'static'
|
||||
data = {'caller': caller,
|
||||
'method_name': method.__name__,
|
||||
'args': args[1:], 'kwargs': kwargs}
|
||||
log.debug('%(caller)s method %(method_name)s '
|
||||
'called with arguments %(args)s %(kwargs)s', data)
|
||||
return method(*args, **kwargs)
|
||||
return wrapper
|
@ -1,60 +0,0 @@
|
||||
# Andreas Jaeger <jaegerandi@gmail.com>, 2016. #zanata
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: oslo.log 3.10.1.dev3\n"
|
||||
"Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n"
|
||||
"POT-Creation-Date: 2016-06-24 09:24+0000\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"PO-Revision-Date: 2016-06-20 06:43+0000\n"
|
||||
"Last-Translator: Andreas Jaeger <jaegerandi@gmail.com>\n"
|
||||
"Language-Team: German\n"
|
||||
"Language: de\n"
|
||||
"X-Generator: Zanata 3.7.3\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
|
||||
|
||||
#, python-format
|
||||
msgid ""
|
||||
"%(what)s is deprecated as of %(as_of)s and may be removed in %(remove_in)s. "
|
||||
"It will not be superseded."
|
||||
msgstr ""
|
||||
"Seit %(as_of)s wird %(what)s nicht mehr unterstützt und voraussichtlich in "
|
||||
"%(remove_in)s entfernt. Es gibt keine Alternative."
|
||||
|
||||
#, python-format
|
||||
msgid ""
|
||||
"%(what)s is deprecated as of %(as_of)s in favor of %(in_favor_of)s and may "
|
||||
"be removed in %(remove_in)s."
|
||||
msgstr ""
|
||||
"Seit %(as_of)s wird %(what)s nicht mehr unterstützt und voraussichtlich in "
|
||||
"%(remove_in)s entfernt. Benutzen Sie %(in_favor_of)s."
|
||||
|
||||
#, python-format
|
||||
msgid "%(what)s is deprecated as of %(as_of)s in favor of %(in_favor_of)s."
|
||||
msgstr ""
|
||||
"Seit %(as_of)s wird %(what)s nicht mehr unterstützt. Benutzen Sie "
|
||||
"%(in_favor_of)s."
|
||||
|
||||
#, python-format
|
||||
msgid "%(what)s is deprecated as of %(as_of)s. It will not be superseded."
|
||||
msgstr ""
|
||||
"Seit %(as_of)s wird %(what)s nicht mehr unterstützt. Es gibt keine "
|
||||
"Alternative."
|
||||
|
||||
#, python-format
|
||||
msgid "Deprecated: %s"
|
||||
msgstr "Nicht weiter unterstützt: %s"
|
||||
|
||||
#, python-format
|
||||
msgid "Error loading logging config %(log_config)s: %(err_msg)s"
|
||||
msgstr ""
|
||||
"Fehler beim Laden der Logging Konfiguration %(log_config)s: %(err_msg)s"
|
||||
|
||||
#, python-format
|
||||
msgid "Fatal call to deprecated config: %(msg)s"
|
||||
msgstr "Aufruf zu nicht weiter unterstützter Konfiguration: %(msg)s"
|
||||
|
||||
#, python-format
|
||||
msgid "syslog facility must be one of: %s"
|
||||
msgstr "Sylog Facility muß einer von %s sein."
|
@ -1,55 +0,0 @@
|
||||
# Andi Chandler <andi@gowling.com>, 2016. #zanata
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: oslo.log 3.11.1.dev4\n"
|
||||
"Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n"
|
||||
"POT-Creation-Date: 2016-07-01 03:32+0000\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"PO-Revision-Date: 2016-06-28 05:56+0000\n"
|
||||
"Last-Translator: Andi Chandler <andi@gowling.com>\n"
|
||||
"Language-Team: English (United Kingdom)\n"
|
||||
"Language: en-GB\n"
|
||||
"X-Generator: Zanata 3.7.3\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
|
||||
|
||||
#, python-format
|
||||
msgid ""
|
||||
"%(what)s is deprecated as of %(as_of)s and may be removed in %(remove_in)s. "
|
||||
"It will not be superseded."
|
||||
msgstr ""
|
||||
"%(what)s is deprecated as of %(as_of)s and may be removed in %(remove_in)s. "
|
||||
"It will not be superseded."
|
||||
|
||||
#, python-format
|
||||
msgid ""
|
||||
"%(what)s is deprecated as of %(as_of)s in favor of %(in_favor_of)s and may "
|
||||
"be removed in %(remove_in)s."
|
||||
msgstr ""
|
||||
"%(what)s is deprecated as of %(as_of)s in favour of %(in_favor_of)s and may "
|
||||
"be removed in %(remove_in)s."
|
||||
|
||||
#, python-format
|
||||
msgid "%(what)s is deprecated as of %(as_of)s in favor of %(in_favor_of)s."
|
||||
msgstr "%(what)s is deprecated as of %(as_of)s in favour of %(in_favor_of)s."
|
||||
|
||||
#, python-format
|
||||
msgid "%(what)s is deprecated as of %(as_of)s. It will not be superseded."
|
||||
msgstr "%(what)s is deprecated as of %(as_of)s. It will not be superseded."
|
||||
|
||||
#, python-format
|
||||
msgid "Deprecated: %s"
|
||||
msgstr "Deprecated: %s"
|
||||
|
||||
#, python-format
|
||||
msgid "Error loading logging config %(log_config)s: %(err_msg)s"
|
||||
msgstr "Error loading logging config %(log_config)s: %(err_msg)s"
|
||||
|
||||
#, python-format
|
||||
msgid "Fatal call to deprecated config: %(msg)s"
|
||||
msgstr "Fatal call to deprecated config: %(msg)s"
|
||||
|
||||
#, python-format
|
||||
msgid "syslog facility must be one of: %s"
|
||||
msgstr "syslog facility must be one of: %s"
|
@ -1,64 +0,0 @@
|
||||
# Translations template for oslo.log.
|
||||
# Copyright (C) 2015 ORGANIZATION
|
||||
# This file is distributed under the same license as the oslo.log project.
|
||||
#
|
||||
# Translators:
|
||||
# Adriana Chisco Landazábal <achisco94@gmail.com>, 2015
|
||||
# Andreas Jaeger <jaegerandi@gmail.com>, 2016. #zanata
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: oslo.log 3.4.1.dev1\n"
|
||||
"Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n"
|
||||
"POT-Creation-Date: 2016-04-19 12:12+0000\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"PO-Revision-Date: 2015-06-22 08:59+0000\n"
|
||||
"Last-Translator: Adriana Chisco Landazábal <achisco94@gmail.com>\n"
|
||||
"Language: es\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"Generated-By: Babel 2.0\n"
|
||||
"X-Generator: Zanata 3.7.3\n"
|
||||
"Language-Team: Spanish\n"
|
||||
|
||||
#, python-format
|
||||
msgid ""
|
||||
"%(what)s is deprecated as of %(as_of)s and may be removed in %(remove_in)s. "
|
||||
"It will not be superseded."
|
||||
msgstr ""
|
||||
"%(what)s está en desuso así como %(as_of)s y puede ser removido en "
|
||||
"%(remove_in)s. No se sustituirá."
|
||||
|
||||
#, python-format
|
||||
msgid ""
|
||||
"%(what)s is deprecated as of %(as_of)s in favor of %(in_favor_of)s and may "
|
||||
"be removed in %(remove_in)s."
|
||||
msgstr ""
|
||||
"%(what)s esté en desuso así como %(as_of)s en beneficio de %(in_favor_of)s y "
|
||||
"puede ser removido en %(remove_in)s."
|
||||
|
||||
#, python-format
|
||||
msgid "%(what)s is deprecated as of %(as_of)s in favor of %(in_favor_of)s."
|
||||
msgstr ""
|
||||
"%(what)s está en desuso así como %(as_of)s en beneficio de %(in_favor_of)s."
|
||||
|
||||
#, python-format
|
||||
msgid "%(what)s is deprecated as of %(as_of)s. It will not be superseded."
|
||||
msgstr "%(what)s está en desuso así como %(as_of)s. No se sustituirá."
|
||||
|
||||
#, python-format
|
||||
msgid "Deprecated: %s"
|
||||
msgstr "En desuso: %s"
|
||||
|
||||
#, python-format
|
||||
msgid "Error loading logging config %(log_config)s: %(err_msg)s"
|
||||
msgstr ""
|
||||
"Error al cargar la configuración de registro %(log_config)s: %(err_msg)s"
|
||||
|
||||
#, python-format
|
||||
msgid "Fatal call to deprecated config: %(msg)s"
|
||||
msgstr "Aviso urgente de configuración en desuso: %(msg)s"
|
||||
|
||||
#, python-format
|
||||
msgid "syslog facility must be one of: %s"
|
||||
msgstr "El recurso syslog debe ser uno de: %s"
|
@ -1,57 +0,0 @@
|
||||
# Andreas Jaeger <jaegerandi@gmail.com>, 2016. #zanata
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: oslo.log 3.4.1.dev1\n"
|
||||
"Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n"
|
||||
"POT-Creation-Date: 2016-04-19 12:12+0000\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"PO-Revision-Date: 2016-02-20 06:53+0000\n"
|
||||
"Last-Translator: KATO Tomoyuki <kato.tomoyuki@jp.fujitsu.com>\n"
|
||||
"Language-Team: Japanese\n"
|
||||
"Language: ja\n"
|
||||
"X-Generator: Zanata 3.7.3\n"
|
||||
"Plural-Forms: nplurals=1; plural=0\n"
|
||||
|
||||
#, python-format
|
||||
msgid ""
|
||||
"%(what)s is deprecated as of %(as_of)s and may be removed in %(remove_in)s. "
|
||||
"It will not be superseded."
|
||||
msgstr ""
|
||||
"%(what)s は %(as_of)s において非推奨になります。%(remove_in)s において削除さ"
|
||||
"れる可能性があります。後継はありません。"
|
||||
|
||||
#, python-format
|
||||
msgid ""
|
||||
"%(what)s is deprecated as of %(as_of)s in favor of %(in_favor_of)s and may "
|
||||
"be removed in %(remove_in)s."
|
||||
msgstr ""
|
||||
"%(what)s は、%(in_favor_of)s に移行するために %(as_of)s において非推奨になり"
|
||||
"ます。 %(remove_in)s において削除される可能性があります。"
|
||||
|
||||
#, python-format
|
||||
msgid "%(what)s is deprecated as of %(as_of)s in favor of %(in_favor_of)s."
|
||||
msgstr ""
|
||||
"%(what)s は、%(in_favor_of)s に移行するために %(as_of)s において非推奨になり"
|
||||
"ます。"
|
||||
|
||||
#, python-format
|
||||
msgid "%(what)s is deprecated as of %(as_of)s. It will not be superseded."
|
||||
msgstr "%(what)s は %(as_of)s において非推奨になります。後継はありません。"
|
||||
|
||||
#, python-format
|
||||
msgid "Deprecated: %s"
|
||||
msgstr "非推奨: %s"
|
||||
|
||||
#, python-format
|
||||
msgid "Error loading logging config %(log_config)s: %(err_msg)s"
|
||||
msgstr "ロギング設定 %(log_config)s の読み込み中にエラー発生: %(err_msg)s"
|
||||
|
||||
#, python-format
|
||||
msgid "Fatal call to deprecated config: %(msg)s"
|
||||
msgstr "非推奨設定の致命的な呼び出し: %(msg)s"
|
||||
|
||||
#, python-format
|
||||
msgid "syslog facility must be one of: %s"
|
||||
msgstr "syslog ファシリティーは次のどれかである必要があります: %s"
|
455
oslo_log/log.py
455
oslo_log/log.py
@ -1,455 +0,0 @@
|
||||
# Copyright 2011 OpenStack Foundation.
|
||||
# Copyright 2010 United States Government as represented by the
|
||||
# Administrator of the National Aeronautics and Space Administration.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
"""OpenStack logging handler.
|
||||
|
||||
This module adds to logging functionality by adding the option to specify
|
||||
a context object when calling the various log methods. If the context object
|
||||
is not specified, default formatting is used. Additionally, an instance uuid
|
||||
may be passed as part of the log message, which is intended to make it easier
|
||||
for admins to find messages related to a specific instance.
|
||||
|
||||
It also allows setting of formatting information through conf.
|
||||
|
||||
"""
|
||||
|
||||
import logging
|
||||
import logging.config
|
||||
import logging.handlers
|
||||
import os
|
||||
import platform
|
||||
import sys
|
||||
try:
|
||||
import syslog
|
||||
except ImportError:
|
||||
syslog = None
|
||||
import traceback
|
||||
|
||||
from oslo_config import cfg
|
||||
from oslo_utils import importutils
|
||||
import six
|
||||
from six import moves
|
||||
|
||||
from oslo_log._i18n import _
|
||||
from oslo_log import _options
|
||||
from oslo_log import formatters
|
||||
from oslo_log import handlers
|
||||
|
||||
CRITICAL = logging.CRITICAL
|
||||
FATAL = logging.FATAL
|
||||
ERROR = logging.ERROR
|
||||
WARNING = logging.WARNING
|
||||
WARN = logging.WARNING
|
||||
INFO = logging.INFO
|
||||
DEBUG = logging.DEBUG
|
||||
NOTSET = logging.NOTSET
|
||||
TRACE = handlers._TRACE
|
||||
|
||||
logging.addLevelName(TRACE, 'TRACE')
|
||||
|
||||
|
||||
def _get_log_file_path(conf, binary=None):
|
||||
logfile = conf.log_file
|
||||
logdir = conf.log_dir
|
||||
|
||||
if logfile and not logdir:
|
||||
return logfile
|
||||
|
||||
if logfile and logdir:
|
||||
return os.path.join(logdir, logfile)
|
||||
|
||||
if logdir:
|
||||
binary = binary or handlers._get_binary_name()
|
||||
return '%s.log' % (os.path.join(logdir, binary),)
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def _iter_loggers():
|
||||
"""Iterate on existing loggers."""
|
||||
|
||||
# Sadly, Logger.manager and Manager.loggerDict are not documented,
|
||||
# but there is no logging public function to iterate on all loggers.
|
||||
|
||||
# The root logger is not part of loggerDict.
|
||||
yield logging.getLogger()
|
||||
|
||||
manager = logging.Logger.manager
|
||||
for logger in manager.loggerDict.values():
|
||||
if isinstance(logger, logging.PlaceHolder):
|
||||
continue
|
||||
yield logger
|
||||
|
||||
|
||||
class BaseLoggerAdapter(logging.LoggerAdapter):
|
||||
|
||||
warn = logging.LoggerAdapter.warning
|
||||
|
||||
@property
|
||||
def handlers(self):
|
||||
return self.logger.handlers
|
||||
|
||||
def trace(self, msg, *args, **kwargs):
|
||||
self.log(TRACE, msg, *args, **kwargs)
|
||||
|
||||
|
||||
class KeywordArgumentAdapter(BaseLoggerAdapter):
|
||||
"""Logger adapter to add keyword arguments to log record's extra data
|
||||
|
||||
Keywords passed to the log call are added to the "extra"
|
||||
dictionary passed to the underlying logger so they are emitted
|
||||
with the log message and available to the format string.
|
||||
|
||||
Special keywords:
|
||||
|
||||
extra
|
||||
An existing dictionary of extra values to be passed to the
|
||||
logger. If present, the dictionary is copied and extended.
|
||||
resource
|
||||
A dictionary-like object containing a ``name`` key or ``type``
|
||||
and ``id`` keys.
|
||||
|
||||
"""
|
||||
|
||||
def process(self, msg, kwargs):
|
||||
# Make a new extra dictionary combining the values we were
|
||||
# given when we were constructed and anything from kwargs.
|
||||
extra = {}
|
||||
extra.update(self.extra)
|
||||
if 'extra' in kwargs:
|
||||
extra.update(kwargs.pop('extra'))
|
||||
# Move any unknown keyword arguments into the extra
|
||||
# dictionary.
|
||||
for name in list(kwargs.keys()):
|
||||
if name == 'exc_info':
|
||||
continue
|
||||
extra[name] = kwargs.pop(name)
|
||||
# NOTE(dhellmann): The gap between when the adapter is called
|
||||
# and when the formatter needs to know what the extra values
|
||||
# are is large enough that we can't get back to the original
|
||||
# extra dictionary easily. We leave a hint to ourselves here
|
||||
# in the form of a list of keys, which will eventually be
|
||||
# attributes of the LogRecord processed by the formatter. That
|
||||
# allows the formatter to know which values were original and
|
||||
# which were extra, so it can treat them differently (see
|
||||
# JSONFormatter for an example of this). We sort the keys so
|
||||
# it is possible to write sane unit tests.
|
||||
extra['extra_keys'] = list(sorted(extra.keys()))
|
||||
# Place the updated extra values back into the keyword
|
||||
# arguments.
|
||||
kwargs['extra'] = extra
|
||||
|
||||
# NOTE(jdg): We would like an easy way to add resource info
|
||||
# to logging, for example a header like 'volume-<uuid>'
|
||||
# Turns out Nova implemented this but it's Nova specific with
|
||||
# instance. Also there's resource_uuid that's been added to
|
||||
# context, but again that only works for Instances, and it
|
||||
# only works for contexts that have the resource id set.
|
||||
resource = kwargs['extra'].get('resource', None)
|
||||
if resource:
|
||||
|
||||
# Many OpenStack resources have a name entry in their db ref
|
||||
# of the form <resource_type>-<uuid>, let's just use that if
|
||||
# it's passed in
|
||||
if not resource.get('name', None):
|
||||
|
||||
# For resources that don't have the name of the format we wish
|
||||
# to use (or places where the LOG call may not have the full
|
||||
# object ref, allow them to pass in a dict:
|
||||
# resource={'type': volume, 'id': uuid}
|
||||
|
||||
resource_type = resource.get('type', None)
|
||||
resource_id = resource.get('id', None)
|
||||
|
||||
if resource_type and resource_id:
|
||||
kwargs['extra']['resource'] = ('[' + resource_type +
|
||||
'-' + resource_id + '] ')
|
||||
else:
|
||||
# FIXME(jdg): Since the name format can be specified via conf
|
||||
# entry, we may want to consider allowing this to be configured
|
||||
# here as well
|
||||
kwargs['extra']['resource'] = ('[' + resource.get('name', '')
|
||||
+ '] ')
|
||||
|
||||
return msg, kwargs
|
||||
|
||||
|
||||
def _create_logging_excepthook(product_name):
|
||||
def logging_excepthook(exc_type, value, tb):
|
||||
extra = {'exc_info': (exc_type, value, tb)}
|
||||
getLogger(product_name).critical(
|
||||
"".join(traceback.format_exception_only(exc_type, value)),
|
||||
**extra)
|
||||
return logging_excepthook
|
||||
|
||||
|
||||
class LogConfigError(Exception):
|
||||
|
||||
message = _('Error loading logging config %(log_config)s: %(err_msg)s')
|
||||
|
||||
def __init__(self, log_config, err_msg):
|
||||
self.log_config = log_config
|
||||
self.err_msg = err_msg
|
||||
|
||||
def __str__(self):
|
||||
return self.message % dict(log_config=self.log_config,
|
||||
err_msg=self.err_msg)
|
||||
|
||||
|
||||
def _load_log_config(log_config_append):
|
||||
try:
|
||||
if not hasattr(_load_log_config, "old_time"):
|
||||
_load_log_config.old_time = 0
|
||||
new_time = os.path.getmtime(log_config_append)
|
||||
if _load_log_config.old_time != new_time:
|
||||
# Reset all existing loggers before reloading config as fileConfig
|
||||
# does not reset non-child loggers.
|
||||
for logger in _iter_loggers():
|
||||
logger.level = logging.NOTSET
|
||||
logger.handlers = []
|
||||
logger.propagate = 1
|
||||
logging.config.fileConfig(log_config_append,
|
||||
disable_existing_loggers=False)
|
||||
_load_log_config.old_time = new_time
|
||||
except (moves.configparser.Error, KeyError, os.error) as exc:
|
||||
raise LogConfigError(log_config_append, six.text_type(exc))
|
||||
|
||||
|
||||
def _mutate_hook(conf, fresh):
|
||||
"""Reconfigures oslo.log according to the mutated options."""
|
||||
|
||||
# verbose is deprecated, so I didn't make it mutable, so there's no need to
|
||||
# test for it here.
|
||||
if (None, 'debug') in fresh:
|
||||
_refresh_root_level(conf.debug, conf.verbose)
|
||||
|
||||
if (None, 'log-config-append') in fresh:
|
||||
_load_log_config.old_time = 0
|
||||
if conf.log_config_append:
|
||||
_load_log_config(conf.log_config_append)
|
||||
|
||||
|
||||
def register_options(conf):
|
||||
"""Register the command line and configuration options used by oslo.log."""
|
||||
|
||||
# Sometimes logging occurs before logging is ready (e.g., oslo_config).
|
||||
# To avoid "No handlers could be found," temporarily log to sys.stderr.
|
||||
root_logger = logging.getLogger(None)
|
||||
if not root_logger.handlers:
|
||||
root_logger.addHandler(logging.StreamHandler())
|
||||
|
||||
conf.register_cli_opts(_options.common_cli_opts)
|
||||
conf.register_cli_opts(_options.logging_cli_opts)
|
||||
conf.register_opts(_options.generic_log_opts)
|
||||
conf.register_opts(_options.log_opts)
|
||||
formatters._store_global_conf(conf)
|
||||
|
||||
conf.register_mutate_hook(_mutate_hook)
|
||||
|
||||
|
||||
def setup(conf, product_name, version='unknown'):
|
||||
"""Setup logging for the current application."""
|
||||
if conf.log_config_append:
|
||||
_load_log_config(conf.log_config_append)
|
||||
else:
|
||||
_setup_logging_from_conf(conf, product_name, version)
|
||||
sys.excepthook = _create_logging_excepthook(product_name)
|
||||
|
||||
|
||||
def set_defaults(logging_context_format_string=None,
|
||||
default_log_levels=None):
|
||||
"""Set default values for the configuration options used by oslo.log."""
|
||||
# Just in case the caller is not setting the
|
||||
# default_log_level. This is insurance because
|
||||
# we introduced the default_log_level parameter
|
||||
# later in a backwards in-compatible change
|
||||
if default_log_levels is not None:
|
||||
cfg.set_defaults(
|
||||
_options.log_opts,
|
||||
default_log_levels=default_log_levels)
|
||||
if logging_context_format_string is not None:
|
||||
cfg.set_defaults(
|
||||
_options.log_opts,
|
||||
logging_context_format_string=logging_context_format_string)
|
||||
|
||||
|
||||
def tempest_set_log_file(filename):
|
||||
"""Provide an API for tempest to set the logging filename.
|
||||
|
||||
.. warning:: Only Tempest should use this function.
|
||||
|
||||
We don't want applications to set a default log file, so we don't
|
||||
want this in set_defaults(). Because tempest doesn't use a
|
||||
configuration file we don't have another convenient way to safely
|
||||
set the log file default.
|
||||
|
||||
"""
|
||||
cfg.set_defaults(_options.logging_cli_opts, log_file=filename)
|
||||
|
||||
|
||||
def _find_facility(facility):
|
||||
# NOTE(jd): Check the validity of facilities at run time as they differ
|
||||
# depending on the OS and Python version being used.
|
||||
valid_facilities = [f for f in
|
||||
["LOG_KERN", "LOG_USER", "LOG_MAIL",
|
||||
"LOG_DAEMON", "LOG_AUTH", "LOG_SYSLOG",
|
||||
"LOG_LPR", "LOG_NEWS", "LOG_UUCP",
|
||||
"LOG_CRON", "LOG_AUTHPRIV", "LOG_FTP",
|
||||
"LOG_LOCAL0", "LOG_LOCAL1", "LOG_LOCAL2",
|
||||
"LOG_LOCAL3", "LOG_LOCAL4", "LOG_LOCAL5",
|
||||
"LOG_LOCAL6", "LOG_LOCAL7"]
|
||||
if getattr(syslog, f, None)]
|
||||
|
||||
facility = facility.upper()
|
||||
|
||||
if not facility.startswith("LOG_"):
|
||||
facility = "LOG_" + facility
|
||||
|
||||
if facility not in valid_facilities:
|
||||
raise TypeError(_('syslog facility must be one of: %s') %
|
||||
', '.join("'%s'" % fac
|
||||
for fac in valid_facilities))
|
||||
|
||||
return getattr(syslog, facility)
|
||||
|
||||
|
||||
def _refresh_root_level(debug, verbose):
|
||||
"""Set the level of the root logger.
|
||||
|
||||
If 'debug' is True, the level will be DEBUG. Otherwise we look at 'verbose'
|
||||
- if that is True, the level will be INFO. If neither are set, the level
|
||||
will be WARNING.
|
||||
|
||||
Note the 'verbose' option is deprecated.
|
||||
|
||||
:param debug
|
||||
:param verbose
|
||||
"""
|
||||
log_root = getLogger(None).logger
|
||||
if debug:
|
||||
log_root.setLevel(logging.DEBUG)
|
||||
elif verbose:
|
||||
log_root.setLevel(logging.INFO)
|
||||
else:
|
||||
log_root.setLevel(logging.WARNING)
|
||||
|
||||
|
||||
def _setup_logging_from_conf(conf, project, version):
|
||||
log_root = getLogger(None).logger
|
||||
|
||||
# Remove all handlers
|
||||
for handler in list(log_root.handlers):
|
||||
log_root.removeHandler(handler)
|
||||
|
||||
logpath = _get_log_file_path(conf)
|
||||
if logpath:
|
||||
if conf.watch_log_file and platform.system() == 'Linux':
|
||||
from oslo_log import watchers
|
||||
file_handler = watchers.FastWatchedFileHandler
|
||||
else:
|
||||
file_handler = logging.handlers.WatchedFileHandler
|
||||
|
||||
filelog = file_handler(logpath)
|
||||
log_root.addHandler(filelog)
|
||||
|
||||
if conf.use_stderr:
|
||||
streamlog = handlers.ColorHandler()
|
||||
log_root.addHandler(streamlog)
|
||||
|
||||
elif not logpath:
|
||||
# pass sys.stdout as a positional argument
|
||||
# python2.6 calls the argument strm, in 2.7 it's stream
|
||||
streamlog = logging.StreamHandler(sys.stdout)
|
||||
log_root.addHandler(streamlog)
|
||||
|
||||
if conf.publish_errors:
|
||||
handler = importutils.import_object(
|
||||
"oslo_messaging.notify.log_handler.PublishErrorsHandler",
|
||||
logging.ERROR)
|
||||
log_root.addHandler(handler)
|
||||
|
||||
if conf.use_syslog:
|
||||
global syslog
|
||||
if syslog is None:
|
||||
raise RuntimeError("syslog is not available on this platform")
|
||||
facility = _find_facility(conf.syslog_log_facility)
|
||||
syslog_handler = handlers.OSSysLogHandler(facility=facility)
|
||||
log_root.addHandler(syslog_handler)
|
||||
|
||||
datefmt = conf.log_date_format
|
||||
for handler in log_root.handlers:
|
||||
handler.setFormatter(formatters.ContextFormatter(project=project,
|
||||
version=version,
|
||||
datefmt=datefmt,
|
||||
config=conf))
|
||||
_refresh_root_level(conf.debug, conf.verbose)
|
||||
|
||||
for pair in conf.default_log_levels:
|
||||
mod, _sep, level_name = pair.partition('=')
|
||||
logger = logging.getLogger(mod)
|
||||
numeric_level = None
|
||||
try:
|
||||
# NOTE(harlowja): integer's are valid level names, and for some
|
||||
# libraries they have a lower level than DEBUG that is typically
|
||||
# defined at level 5, so to make that accessible, try to convert
|
||||
# this to a integer, and if not keep the original...
|
||||
numeric_level = int(level_name)
|
||||
except ValueError: # nosec
|
||||
pass
|
||||
if numeric_level is not None:
|
||||
logger.setLevel(numeric_level)
|
||||
else:
|
||||
logger.setLevel(level_name)
|
||||
|
||||
_loggers = {}
|
||||
|
||||
|
||||
def getLogger(name=None, project='unknown', version='unknown'):
|
||||
"""Build a logger with the given name.
|
||||
|
||||
:param name: The name for the logger. This is usually the module
|
||||
name, ``__name__``.
|
||||
:type name: string
|
||||
:param project: The name of the project, to be injected into log
|
||||
messages. For example, ``'nova'``.
|
||||
:type project: string
|
||||
:param version: The version of the project, to be injected into log
|
||||
messages. For example, ``'2014.2'``.
|
||||
:type version: string
|
||||
"""
|
||||
# NOTE(dhellmann): To maintain backwards compatibility with the
|
||||
# old oslo namespace package logger configurations, and to make it
|
||||
# possible to control all oslo logging with one logger node, we
|
||||
# replace "oslo_" with "oslo." so that modules under the new
|
||||
# non-namespaced packages get loggers as though they are.
|
||||
if name and name.startswith('oslo_'):
|
||||
name = 'oslo.' + name[5:]
|
||||
if name not in _loggers:
|
||||
_loggers[name] = KeywordArgumentAdapter(logging.getLogger(name),
|
||||
{'project': project,
|
||||
'version': version})
|
||||
return _loggers[name]
|
||||
|
||||
|
||||
def get_default_log_levels():
|
||||
"""Return the Oslo Logging default log levels.
|
||||
|
||||
Returns a copy of the list so an application can change the value
|
||||
and not affect the default value used in the log_opts configuration
|
||||
setup.
|
||||
"""
|
||||
return list(_options.DEFAULT_LOG_LEVELS)
|
@ -1,29 +0,0 @@
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import logging
|
||||
|
||||
from oslo_log import versionutils
|
||||
|
||||
|
||||
@versionutils.deprecated(
|
||||
versionutils.deprecated.LIBERTY,
|
||||
remove_in=+1)
|
||||
class WritableLogger(object):
|
||||
"""A thin wrapper that responds to `write` and logs."""
|
||||
|
||||
def __init__(self, logger, level=logging.INFO):
|
||||
self.logger = logger
|
||||
self.level = level
|
||||
|
||||
def write(self, msg):
|
||||
self.logger.log(self.level, msg.rstrip())
|
@ -1,13 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
@ -1,13 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
@ -1,31 +0,0 @@
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
|
||||
from oslo_log import fixture
|
||||
from oslo_log import log as logging
|
||||
from oslotest import base as test_base
|
||||
|
||||
|
||||
class TestLoggingFixture(test_base.BaseTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestLoggingFixture, self).setUp()
|
||||
self.log = logging.getLogger(__name__)
|
||||
|
||||
def test_logging_handle_error(self):
|
||||
self.log.error('pid of first child is %(foo)s', 1)
|
||||
self.useFixture(fixture.get_logging_handle_error_fixture())
|
||||
self.assertRaises(TypeError,
|
||||
self.log.error,
|
||||
'pid of first child is %(foo)s',
|
||||
1)
|
@ -1,36 +0,0 @@
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import logging
|
||||
|
||||
from oslo_log import fixture
|
||||
from oslotest import base as test_base
|
||||
|
||||
|
||||
class TestSetLevelFixture(test_base.BaseTestCase):
|
||||
|
||||
def test_unset_before(self):
|
||||
logger = logging.getLogger('no-such-logger-unset')
|
||||
self.assertEqual(logging.NOTSET, logger.level)
|
||||
fix = fixture.SetLogLevel(['no-such-logger-unset'], logging.DEBUG)
|
||||
with fix:
|
||||
self.assertEqual(logging.DEBUG, logger.level)
|
||||
self.assertEqual(logging.NOTSET, logger.level)
|
||||
|
||||
def test_set_before(self):
|
||||
logger = logging.getLogger('no-such-logger-set')
|
||||
logger.setLevel(logging.ERROR)
|
||||
self.assertEqual(logging.ERROR, logger.level)
|
||||
fix = fixture.SetLogLevel(['no-such-logger-set'], logging.DEBUG)
|
||||
with fix:
|
||||
self.assertEqual(logging.DEBUG, logger.level)
|
||||
self.assertEqual(logging.ERROR, logger.level)
|
@ -1,85 +0,0 @@
|
||||
# Copyright (c) 2016 OpenStack Foundation
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
"""Unit Tests for oslo.log formatter"""
|
||||
|
||||
import mock
|
||||
|
||||
from oslo_context import context
|
||||
from oslo_log import formatters
|
||||
from oslotest import base as test_base
|
||||
|
||||
|
||||
def _fake_context():
|
||||
ctxt = context.RequestContext(user="user",
|
||||
tenant="tenant",
|
||||
project_domain="pdomain",
|
||||
user_domain="udomain",
|
||||
overwrite=True)
|
||||
|
||||
return ctxt
|
||||
|
||||
|
||||
class AlternativeRequestContext(object):
|
||||
|
||||
def __init__(self, user=None, tenant=None):
|
||||
self.user = user
|
||||
self.tenant = tenant
|
||||
|
||||
def to_dict(self):
|
||||
return {'user': self.user,
|
||||
'tenant': self.tenant}
|
||||
|
||||
|
||||
class FormatterTest(test_base.BaseTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(FormatterTest, self).setUp()
|
||||
|
||||
def test_replace_false_value_exists(self):
|
||||
d = {"user": "user1"}
|
||||
s = "%(user)s" % formatters._ReplaceFalseValue(d)
|
||||
self.assertEqual(d['user'], s)
|
||||
|
||||
def test_replace_false_value_not_exists(self):
|
||||
d = {"user": "user1"}
|
||||
s = "%(project)s" % formatters._ReplaceFalseValue(d)
|
||||
self.assertEqual("-", s)
|
||||
|
||||
def test_dictify_context_empty(self):
|
||||
self.assertEqual({}, formatters._dictify_context(None))
|
||||
|
||||
@mock.patch("debtcollector.deprecate")
|
||||
def test_dictify_context_with_dict(self, mock_deprecate):
|
||||
d = {"user": "user"}
|
||||
self.assertEqual(d, formatters._dictify_context(d))
|
||||
mock_deprecate.assert_not_called()
|
||||
|
||||
@mock.patch("debtcollector.deprecate")
|
||||
def test_dictify_context_with_context(self, mock_deprecate):
|
||||
ctxt = _fake_context()
|
||||
self.assertEqual(ctxt.get_logging_values(),
|
||||
formatters._dictify_context(ctxt))
|
||||
mock_deprecate.assert_not_called()
|
||||
|
||||
@mock.patch("debtcollector.deprecate")
|
||||
def test_dictify_context_without_get_logging_values(self, mock_deprecate):
|
||||
ctxt = AlternativeRequestContext(user="user", tenant="tenant")
|
||||
d = {"user": "user", "tenant": "tenant"}
|
||||
self.assertEqual(d, formatters._dictify_context(ctxt))
|
||||
mock_deprecate.assert_called_with(
|
||||
'The RequestContext.get_logging_values() '
|
||||
'method should be defined for logging context specific '
|
||||
'information. The to_dict() method is deprecated '
|
||||
'for oslo.log use.', removal_version='5.0.0', version='3.8.0')
|
@ -1,62 +0,0 @@
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import mock
|
||||
from oslo_log import helpers
|
||||
from oslotest import base as test_base
|
||||
|
||||
|
||||
@helpers.log_method_call
|
||||
def _static_method():
|
||||
pass
|
||||
|
||||
|
||||
class LogHelpersTestCase(test_base.BaseTestCase):
|
||||
|
||||
def test_log_decorator(self):
|
||||
'''Test that LOG.debug is called with proper arguments.'''
|
||||
|
||||
class test_class(object):
|
||||
@helpers.log_method_call
|
||||
def test_method(self, arg1, arg2, arg3, *args, **kwargs):
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
@helpers.log_method_call
|
||||
def test_classmethod(cls, arg1, arg2, arg3, *args, **kwargs):
|
||||
pass
|
||||
|
||||
args = tuple(range(6))
|
||||
kwargs = {'kwarg1': 6, 'kwarg2': 7}
|
||||
|
||||
obj = test_class()
|
||||
for method_name in ('test_method', 'test_classmethod'):
|
||||
data = {'caller': helpers._get_full_class_name(test_class),
|
||||
'method_name': method_name,
|
||||
'args': args,
|
||||
'kwargs': kwargs}
|
||||
|
||||
method = getattr(obj, method_name)
|
||||
with mock.patch('logging.Logger.debug') as debug:
|
||||
method(*args, **kwargs)
|
||||
debug.assert_called_with(mock.ANY, data)
|
||||
|
||||
def test_log_decorator_for_static(self):
|
||||
'''Test that LOG.debug is called with proper arguments.'''
|
||||
|
||||
data = {'caller': 'static',
|
||||
'method_name': '_static_method',
|
||||
'args': (),
|
||||
'kwargs': {}}
|
||||
with mock.patch('logging.Logger.debug') as debug:
|
||||
_static_method()
|
||||
debug.assert_called_with(mock.ANY, data)
|
File diff suppressed because it is too large
Load Diff
@ -1,371 +0,0 @@
|
||||
# Copyright (c) 2013 OpenStack Foundation
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import mock
|
||||
from oslotest import base as test_base
|
||||
import six
|
||||
from testtools import matchers
|
||||
import unittest2
|
||||
|
||||
from oslo_log import versionutils
|
||||
|
||||
|
||||
class DeprecatedTestCase(test_base.BaseTestCase):
|
||||
def assert_deprecated(self, mock_reporter, no_removal=False,
|
||||
**expected_details):
|
||||
if 'in_favor_of' in expected_details:
|
||||
if no_removal is False:
|
||||
expected_msg = versionutils._deprecated_msg_with_alternative
|
||||
else:
|
||||
expected_msg = getattr(
|
||||
versionutils,
|
||||
'_deprecated_msg_with_alternative_no_removal')
|
||||
else:
|
||||
if no_removal is False:
|
||||
expected_msg = versionutils._deprecated_msg_no_alternative
|
||||
else:
|
||||
expected_msg = getattr(
|
||||
versionutils,
|
||||
'_deprecated_msg_with_no_alternative_no_removal')
|
||||
# The first argument is the logger, and we don't care about
|
||||
# that, so ignore it with ANY.
|
||||
mock_reporter.assert_called_with(mock.ANY,
|
||||
expected_msg,
|
||||
expected_details)
|
||||
|
||||
@mock.patch('oslo_log.versionutils.report_deprecated_feature')
|
||||
def test_deprecating_a_function_returns_correct_value(self, mock_reporter):
|
||||
|
||||
@versionutils.deprecated(as_of=versionutils.deprecated.ICEHOUSE)
|
||||
def do_outdated_stuff(data):
|
||||
return data
|
||||
|
||||
expected_rv = 'expected return value'
|
||||
retval = do_outdated_stuff(expected_rv)
|
||||
|
||||
self.assertThat(retval, matchers.Equals(expected_rv))
|
||||
|
||||
@mock.patch('oslo_log.versionutils.report_deprecated_feature')
|
||||
def test_deprecating_a_method_returns_correct_value(self, mock_reporter):
|
||||
|
||||
class C(object):
|
||||
@versionutils.deprecated(as_of=versionutils.deprecated.ICEHOUSE)
|
||||
def outdated_method(self, *args):
|
||||
return args
|
||||
|
||||
retval = C().outdated_method(1, 'of anything')
|
||||
|
||||
self.assertThat(retval, matchers.Equals((1, 'of anything')))
|
||||
|
||||
@mock.patch('oslo_log.versionutils.report_deprecated_feature')
|
||||
def test_deprecated_with_unknown_future_release(self, mock_reporter):
|
||||
|
||||
@versionutils.deprecated(as_of=versionutils.deprecated.BEXAR,
|
||||
in_favor_of='different_stuff()')
|
||||
def do_outdated_stuff():
|
||||
return
|
||||
|
||||
do_outdated_stuff()
|
||||
|
||||
self.assert_deprecated(mock_reporter,
|
||||
what='do_outdated_stuff()',
|
||||
in_favor_of='different_stuff()',
|
||||
as_of='Bexar',
|
||||
remove_in='D')
|
||||
|
||||
@mock.patch('oslo_log.versionutils.report_deprecated_feature')
|
||||
def test_deprecated_with_known_future_release(self, mock_reporter):
|
||||
|
||||
@versionutils.deprecated(as_of=versionutils.deprecated.GRIZZLY,
|
||||
in_favor_of='different_stuff()')
|
||||
def do_outdated_stuff():
|
||||
return
|
||||
|
||||
do_outdated_stuff()
|
||||
|
||||
self.assert_deprecated(mock_reporter,
|
||||
what='do_outdated_stuff()',
|
||||
in_favor_of='different_stuff()',
|
||||
as_of='Grizzly',
|
||||
remove_in='Icehouse')
|
||||
|
||||
@mock.patch('oslo_log.versionutils.report_deprecated_feature')
|
||||
def test_deprecated_without_replacement(self, mock_reporter):
|
||||
|
||||
@versionutils.deprecated(as_of=versionutils.deprecated.GRIZZLY)
|
||||
def do_outdated_stuff():
|
||||
return
|
||||
|
||||
do_outdated_stuff()
|
||||
|
||||
self.assert_deprecated(mock_reporter,
|
||||
what='do_outdated_stuff()',
|
||||
as_of='Grizzly',
|
||||
remove_in='Icehouse')
|
||||
|
||||
@mock.patch('oslo_log.versionutils.report_deprecated_feature')
|
||||
def test_deprecated_with_custom_what(self, mock_reporter):
|
||||
|
||||
@versionutils.deprecated(as_of=versionutils.deprecated.GRIZZLY,
|
||||
what='v2.0 API',
|
||||
in_favor_of='v3 API')
|
||||
def do_outdated_stuff():
|
||||
return
|
||||
|
||||
do_outdated_stuff()
|
||||
|
||||
self.assert_deprecated(mock_reporter,
|
||||
what='v2.0 API',
|
||||
in_favor_of='v3 API',
|
||||
as_of='Grizzly',
|
||||
remove_in='Icehouse')
|
||||
|
||||
@mock.patch('oslo_log.versionutils.report_deprecated_feature')
|
||||
def test_deprecated_with_removed_next_release(self, mock_reporter):
|
||||
|
||||
@versionutils.deprecated(as_of=versionutils.deprecated.GRIZZLY,
|
||||
remove_in=1)
|
||||
def do_outdated_stuff():
|
||||
return
|
||||
|
||||
do_outdated_stuff()
|
||||
|
||||
self.assert_deprecated(mock_reporter,
|
||||
what='do_outdated_stuff()',
|
||||
as_of='Grizzly',
|
||||
remove_in='Havana')
|
||||
|
||||
@mock.patch('oslo_log.versionutils.report_deprecated_feature')
|
||||
def test_deprecated_with_removed_plus_3(self, mock_reporter):
|
||||
|
||||
@versionutils.deprecated(as_of=versionutils.deprecated.GRIZZLY,
|
||||
remove_in=+3)
|
||||
def do_outdated_stuff():
|
||||
return
|
||||
|
||||
do_outdated_stuff()
|
||||
|
||||
self.assert_deprecated(mock_reporter,
|
||||
what='do_outdated_stuff()',
|
||||
as_of='Grizzly',
|
||||
remove_in='Juno')
|
||||
|
||||
@mock.patch('oslo_log.versionutils.report_deprecated_feature')
|
||||
def test_deprecated_with_removed_zero(self, mock_reporter):
|
||||
@versionutils.deprecated(as_of=versionutils.deprecated.GRIZZLY,
|
||||
remove_in=0)
|
||||
def do_outdated_stuff():
|
||||
return
|
||||
|
||||
do_outdated_stuff()
|
||||
self.assert_deprecated(mock_reporter,
|
||||
no_removal=True,
|
||||
what='do_outdated_stuff()',
|
||||
as_of='Grizzly',
|
||||
remove_in='Grizzly')
|
||||
|
||||
@mock.patch('oslo_log.versionutils.report_deprecated_feature')
|
||||
def test_deprecated_with_removed_none(self, mock_reporter):
|
||||
@versionutils.deprecated(as_of=versionutils.deprecated.GRIZZLY,
|
||||
remove_in=None)
|
||||
def do_outdated_stuff():
|
||||
return
|
||||
|
||||
do_outdated_stuff()
|
||||
self.assert_deprecated(mock_reporter,
|
||||
no_removal=True,
|
||||
what='do_outdated_stuff()',
|
||||
as_of='Grizzly',
|
||||
remove_in='Grizzly')
|
||||
|
||||
@mock.patch('oslo_log.versionutils.report_deprecated_feature')
|
||||
def test_deprecated_with_removed_zero_and_alternative(self, mock_reporter):
|
||||
@versionutils.deprecated(as_of=versionutils.deprecated.GRIZZLY,
|
||||
in_favor_of='different_stuff()',
|
||||
remove_in=0)
|
||||
def do_outdated_stuff():
|
||||
return
|
||||
|
||||
do_outdated_stuff()
|
||||
self.assert_deprecated(mock_reporter,
|
||||
no_removal=True,
|
||||
what='do_outdated_stuff()',
|
||||
as_of='Grizzly',
|
||||
in_favor_of='different_stuff()',
|
||||
remove_in='Grizzly')
|
||||
|
||||
@mock.patch('oslo_log.versionutils.report_deprecated_feature')
|
||||
def test_deprecated_class_without_init(self, mock_reporter):
|
||||
|
||||
@versionutils.deprecated(as_of=versionutils.deprecated.JUNO,
|
||||
remove_in=+1)
|
||||
class OutdatedClass(object):
|
||||
pass
|
||||
obj = OutdatedClass()
|
||||
|
||||
self.assertIsInstance(obj, OutdatedClass)
|
||||
self.assert_deprecated(mock_reporter,
|
||||
what='OutdatedClass()',
|
||||
as_of='Juno',
|
||||
remove_in='Kilo')
|
||||
|
||||
@mock.patch('oslo_log.versionutils.report_deprecated_feature')
|
||||
def test_deprecated_class_with_init(self, mock_reporter):
|
||||
mock_arguments = mock.MagicMock()
|
||||
args = (1, 5, 7)
|
||||
kwargs = {'first': 10, 'second': 20}
|
||||
|
||||
@versionutils.deprecated(as_of=versionutils.deprecated.JUNO,
|
||||
remove_in=+1)
|
||||
class OutdatedClass(object):
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""It is __init__ method."""
|
||||
mock_arguments.args = args
|
||||
mock_arguments.kwargs = kwargs
|
||||
super(OutdatedClass, self).__init__()
|
||||
obj = OutdatedClass(*args, **kwargs)
|
||||
|
||||
self.assertIsInstance(obj, OutdatedClass)
|
||||
self.assertEqual('__init__', obj.__init__.__name__)
|
||||
self.assertEqual('It is __init__ method.', obj.__init__.__doc__)
|
||||
self.assertEqual(args, mock_arguments.args)
|
||||
self.assertEqual(kwargs, mock_arguments.kwargs)
|
||||
self.assert_deprecated(mock_reporter,
|
||||
what='OutdatedClass()',
|
||||
as_of='Juno',
|
||||
remove_in='Kilo')
|
||||
|
||||
@unittest2.skipIf(
|
||||
six.PY3,
|
||||
'Deprecated exception detection does not work for Python 3')
|
||||
@mock.patch('oslo_log.versionutils.report_deprecated_feature')
|
||||
def test_deprecated_exception(self, mock_log):
|
||||
@versionutils.deprecated(as_of=versionutils.deprecated.ICEHOUSE,
|
||||
remove_in=+1)
|
||||
class OldException(Exception):
|
||||
pass
|
||||
|
||||
class NewException(OldException):
|
||||
pass
|
||||
|
||||
try:
|
||||
raise NewException()
|
||||
except OldException:
|
||||
pass
|
||||
|
||||
self.assert_deprecated(mock_log, what='OldException()',
|
||||
as_of='Icehouse', remove_in='Juno')
|
||||
|
||||
@mock.patch('oslo_log.versionutils.report_deprecated_feature')
|
||||
def test_deprecated_exception_old(self, mock_log):
|
||||
@versionutils.deprecated(as_of=versionutils.deprecated.ICEHOUSE,
|
||||
remove_in=+1)
|
||||
class OldException(Exception):
|
||||
pass
|
||||
|
||||
try:
|
||||
raise OldException()
|
||||
except OldException:
|
||||
pass
|
||||
|
||||
self.assert_deprecated(mock_log, what='OldException()',
|
||||
as_of='Icehouse', remove_in='Juno')
|
||||
|
||||
@mock.patch('oslo_log.versionutils.report_deprecated_feature')
|
||||
def test_deprecated_exception_new(self, mock_log):
|
||||
@versionutils.deprecated(as_of=versionutils.deprecated.ICEHOUSE,
|
||||
remove_in=+1)
|
||||
class OldException(Exception):
|
||||
pass
|
||||
|
||||
class NewException(OldException):
|
||||
pass
|
||||
|
||||
try:
|
||||
raise NewException()
|
||||
except NewException:
|
||||
pass
|
||||
|
||||
mock_log.assert_not_called()
|
||||
|
||||
@mock.patch('oslo_log.versionutils.report_deprecated_feature')
|
||||
def test_deprecated_exception_unrelated(self, mock_log):
|
||||
@versionutils.deprecated(as_of=versionutils.deprecated.ICEHOUSE,
|
||||
remove_in=+1)
|
||||
class OldException(Exception):
|
||||
pass
|
||||
|
||||
class UnrelatedException(Exception):
|
||||
pass
|
||||
|
||||
try:
|
||||
raise UnrelatedException()
|
||||
except UnrelatedException:
|
||||
pass
|
||||
|
||||
mock_log.assert_not_called()
|
||||
|
||||
@mock.patch.object(versionutils.CONF, 'register_opts')
|
||||
def test_register_options(self, mock_register_opts):
|
||||
# Calling register_options registers the config options.
|
||||
|
||||
versionutils.register_options()
|
||||
|
||||
mock_register_opts.assert_called_once_with(
|
||||
versionutils.deprecated_opts)
|
||||
|
||||
@mock.patch('oslo_log.versionutils.report_deprecated_feature')
|
||||
def test_deprecated_mitaka_plus_two(self, mock_reporter):
|
||||
|
||||
@versionutils.deprecated(as_of=versionutils.deprecated.MITAKA,
|
||||
remove_in=+2)
|
||||
class OutdatedClass(object):
|
||||
pass
|
||||
obj = OutdatedClass()
|
||||
|
||||
self.assertIsInstance(obj, OutdatedClass)
|
||||
self.assert_deprecated(mock_reporter,
|
||||
what='OutdatedClass()',
|
||||
as_of='Mitaka',
|
||||
remove_in='Ocata')
|
||||
|
||||
@mock.patch('oslo_log.versionutils.report_deprecated_feature')
|
||||
def test_deprecated_newton_plus_two(self, mock_reporter):
|
||||
|
||||
@versionutils.deprecated(as_of=versionutils.deprecated.NEWTON,
|
||||
remove_in=+2)
|
||||
class OutdatedClass(object):
|
||||
pass
|
||||
obj = OutdatedClass()
|
||||
|
||||
self.assertIsInstance(obj, OutdatedClass)
|
||||
self.assert_deprecated(mock_reporter,
|
||||
what='OutdatedClass()',
|
||||
as_of='Newton',
|
||||
remove_in='P')
|
||||
|
||||
@mock.patch('oslo_log.versionutils.report_deprecated_feature')
|
||||
def test_deprecated_message(self, mock_reporter):
|
||||
|
||||
versionutils.deprecation_warning('outdated_stuff',
|
||||
as_of=versionutils.deprecated.KILO,
|
||||
in_favor_of='different_stuff',
|
||||
remove_in=+2)
|
||||
|
||||
self.assert_deprecated(mock_reporter,
|
||||
what='outdated_stuff',
|
||||
in_favor_of='different_stuff',
|
||||
as_of='Kilo',
|
||||
remove_in='Mitaka')
|
@ -1,18 +0,0 @@
|
||||
# Copyright 2016 OpenStack Foundation
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
|
||||
import pbr.version
|
||||
|
||||
version_info = pbr.version.VersionInfo('oslo_log')
|
@ -1,302 +0,0 @@
|
||||
# Copyright (c) 2013 OpenStack Foundation
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
"""
|
||||
Helpers for comparing version strings.
|
||||
"""
|
||||
|
||||
import functools
|
||||
import inspect
|
||||
import logging
|
||||
|
||||
from oslo_config import cfg
|
||||
import six
|
||||
|
||||
from oslo_log._i18n import _
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
CONF = cfg.CONF
|
||||
_DEPRECATED_EXCEPTIONS = set()
|
||||
|
||||
|
||||
deprecated_opts = [
|
||||
cfg.BoolOpt('fatal_deprecations',
|
||||
default=False,
|
||||
help='Enables or disables fatal status of deprecations.'),
|
||||
]
|
||||
|
||||
|
||||
_deprecated_msg_with_alternative = _(
|
||||
'%(what)s is deprecated as of %(as_of)s in favor of '
|
||||
'%(in_favor_of)s and may be removed in %(remove_in)s.')
|
||||
|
||||
_deprecated_msg_no_alternative = _(
|
||||
'%(what)s is deprecated as of %(as_of)s and may be '
|
||||
'removed in %(remove_in)s. It will not be superseded.')
|
||||
|
||||
_deprecated_msg_with_alternative_no_removal = _(
|
||||
'%(what)s is deprecated as of %(as_of)s in favor of %(in_favor_of)s.')
|
||||
|
||||
_deprecated_msg_with_no_alternative_no_removal = _(
|
||||
'%(what)s is deprecated as of %(as_of)s. It will not be superseded.')
|
||||
|
||||
|
||||
_RELEASES = {
|
||||
# NOTE(morganfainberg): Bexar is used for unit test purposes, it is
|
||||
# expected we maintain a gap between Bexar and Folsom in this list.
|
||||
'B': 'Bexar',
|
||||
'F': 'Folsom',
|
||||
'G': 'Grizzly',
|
||||
'H': 'Havana',
|
||||
'I': 'Icehouse',
|
||||
'J': 'Juno',
|
||||
'K': 'Kilo',
|
||||
'L': 'Liberty',
|
||||
'M': 'Mitaka',
|
||||
'N': 'Newton',
|
||||
'O': 'Ocata',
|
||||
}
|
||||
|
||||
|
||||
def register_options():
|
||||
"""Register configuration options used by this library.
|
||||
|
||||
.. note: This is optional since the options are also registered
|
||||
automatically when the functions in this module are used.
|
||||
|
||||
"""
|
||||
CONF.register_opts(deprecated_opts)
|
||||
|
||||
|
||||
class deprecated(object):
|
||||
"""A decorator to mark callables as deprecated.
|
||||
|
||||
This decorator logs a deprecation message when the callable it decorates is
|
||||
used. The message will include the release where the callable was
|
||||
deprecated, the release where it may be removed and possibly an optional
|
||||
replacement. It also logs a message when a deprecated exception is being
|
||||
caught in a try-except block, but not when subclasses of that exception
|
||||
are being caught.
|
||||
|
||||
Examples:
|
||||
|
||||
1. Specifying the required deprecated release
|
||||
|
||||
>>> @deprecated(as_of=deprecated.ICEHOUSE)
|
||||
... def a(): pass
|
||||
|
||||
2. Specifying a replacement:
|
||||
|
||||
>>> @deprecated(as_of=deprecated.ICEHOUSE, in_favor_of='f()')
|
||||
... def b(): pass
|
||||
|
||||
3. Specifying the release where the functionality may be removed:
|
||||
|
||||
>>> @deprecated(as_of=deprecated.ICEHOUSE, remove_in=+1)
|
||||
... def c(): pass
|
||||
|
||||
4. Specifying the deprecated functionality will not be removed:
|
||||
|
||||
>>> @deprecated(as_of=deprecated.ICEHOUSE, remove_in=None)
|
||||
... def d(): pass
|
||||
|
||||
5. Specifying a replacement, deprecated functionality will not be removed:
|
||||
|
||||
>>> @deprecated(as_of=deprecated.ICEHOUSE, in_favor_of='f()',
|
||||
... remove_in=None)
|
||||
... def e(): pass
|
||||
|
||||
.. warning::
|
||||
|
||||
The hook used to detect when a deprecated exception is being
|
||||
*caught* does not work under Python 3. Deprecated exceptions
|
||||
are still logged if they are thrown.
|
||||
|
||||
"""
|
||||
|
||||
# NOTE(morganfainberg): Bexar is used for unit test purposes, it is
|
||||
# expected we maintain a gap between Bexar and Folsom in this list.
|
||||
BEXAR = 'B'
|
||||
FOLSOM = 'F'
|
||||
GRIZZLY = 'G'
|
||||
HAVANA = 'H'
|
||||
ICEHOUSE = 'I'
|
||||
JUNO = 'J'
|
||||
KILO = 'K'
|
||||
LIBERTY = 'L'
|
||||
MITAKA = 'M'
|
||||
NEWTON = 'N'
|
||||
OCATA = 'O'
|
||||
|
||||
def __init__(self, as_of, in_favor_of=None, remove_in=2, what=None):
|
||||
"""Initialize decorator
|
||||
|
||||
:param as_of: the release deprecating the callable. Constants
|
||||
are define in this class for convenience.
|
||||
:param in_favor_of: the replacement for the callable (optional)
|
||||
:param remove_in: an integer specifying how many releases to wait
|
||||
before removing (default: 2)
|
||||
:param what: name of the thing being deprecated (default: the
|
||||
callable's name)
|
||||
|
||||
"""
|
||||
self.as_of = as_of
|
||||
self.in_favor_of = in_favor_of
|
||||
self.remove_in = remove_in
|
||||
self.what = what
|
||||
|
||||
def __call__(self, func_or_cls):
|
||||
report_deprecated = functools.partial(
|
||||
deprecation_warning,
|
||||
what=self.what or func_or_cls.__name__ + '()',
|
||||
as_of=self.as_of,
|
||||
in_favor_of=self.in_favor_of,
|
||||
remove_in=self.remove_in)
|
||||
|
||||
if inspect.isfunction(func_or_cls):
|
||||
|
||||
@six.wraps(func_or_cls)
|
||||
def wrapped(*args, **kwargs):
|
||||
report_deprecated()
|
||||
return func_or_cls(*args, **kwargs)
|
||||
return wrapped
|
||||
elif inspect.isclass(func_or_cls):
|
||||
orig_init = func_or_cls.__init__
|
||||
|
||||
# TODO(tsufiev): change `functools` module to `six` as
|
||||
# soon as six 1.7.4 (with fix for passing `assigned`
|
||||
# argument to underlying `functools.wraps`) is released
|
||||
# and added to the oslo-incubator requrements
|
||||
@functools.wraps(orig_init, assigned=('__name__', '__doc__'))
|
||||
def new_init(self, *args, **kwargs):
|
||||
if self.__class__ in _DEPRECATED_EXCEPTIONS:
|
||||
report_deprecated()
|
||||
orig_init(self, *args, **kwargs)
|
||||
func_or_cls.__init__ = new_init
|
||||
_DEPRECATED_EXCEPTIONS.add(func_or_cls)
|
||||
|
||||
if issubclass(func_or_cls, Exception):
|
||||
# NOTE(dhellmann): The subclasscheck is called,
|
||||
# sometimes, to test whether a class matches the type
|
||||
# being caught in an exception. This lets us warn
|
||||
# folks that they are trying to catch an exception
|
||||
# that has been deprecated. However, under Python 3
|
||||
# the test for whether one class is a subclass of
|
||||
# another has been optimized so that the abstract
|
||||
# check is only invoked in some cases. (See
|
||||
# PyObject_IsSubclass in cpython/Objects/abstract.c
|
||||
# for the short-cut.)
|
||||
class ExceptionMeta(type):
|
||||
def __subclasscheck__(self, subclass):
|
||||
if self in _DEPRECATED_EXCEPTIONS:
|
||||
report_deprecated()
|
||||
return super(ExceptionMeta,
|
||||
self).__subclasscheck__(subclass)
|
||||
func_or_cls = six.add_metaclass(ExceptionMeta)(func_or_cls)
|
||||
_DEPRECATED_EXCEPTIONS.add(func_or_cls)
|
||||
|
||||
return func_or_cls
|
||||
else:
|
||||
raise TypeError('deprecated can be used only with functions or '
|
||||
'classes')
|
||||
|
||||
|
||||
def _get_safe_to_remove_release(release, remove_in):
|
||||
# TODO(dstanek): this method will have to be reimplemented once
|
||||
# when we get to the X release because once we get to the Y
|
||||
# release, what is Y+2?
|
||||
if remove_in is None:
|
||||
remove_in = 0
|
||||
new_release = chr(ord(release) + remove_in)
|
||||
if new_release in _RELEASES:
|
||||
return _RELEASES[new_release]
|
||||
else:
|
||||
return new_release
|
||||
|
||||
|
||||
def deprecation_warning(what, as_of, in_favor_of=None,
|
||||
remove_in=2, logger=LOG):
|
||||
"""Warn about the deprecation of a feature.
|
||||
|
||||
:param what: name of the thing being deprecated.
|
||||
:param as_of: the release deprecating the callable.
|
||||
:param in_favor_of: the replacement for the callable (optional)
|
||||
:param remove_in: an integer specifying how many releases to wait
|
||||
before removing (default: 2)
|
||||
:param logger: the logging object to use for reporting (optional).
|
||||
"""
|
||||
details = dict(what=what,
|
||||
as_of=_RELEASES[as_of],
|
||||
remove_in=_get_safe_to_remove_release(as_of, remove_in))
|
||||
|
||||
if in_favor_of:
|
||||
details['in_favor_of'] = in_favor_of
|
||||
if remove_in is not None and remove_in > 0:
|
||||
msg = _deprecated_msg_with_alternative
|
||||
else:
|
||||
# There are no plans to remove this function, but it is
|
||||
# now deprecated.
|
||||
msg = _deprecated_msg_with_alternative_no_removal
|
||||
else:
|
||||
if remove_in is not None and remove_in > 0:
|
||||
msg = _deprecated_msg_no_alternative
|
||||
else:
|
||||
# There are no plans to remove this function, but it is
|
||||
# now deprecated.
|
||||
msg = _deprecated_msg_with_no_alternative_no_removal
|
||||
|
||||
report_deprecated_feature(logger, msg, details)
|
||||
|
||||
|
||||
# Track the messages we have sent already. See
|
||||
# report_deprecated_feature().
|
||||
_deprecated_messages_sent = {}
|
||||
|
||||
|
||||
def report_deprecated_feature(logger, msg, *args, **kwargs):
|
||||
"""Call this function when a deprecated feature is used.
|
||||
|
||||
If the system is configured for fatal deprecations then the message
|
||||
is logged at the 'critical' level and :class:`DeprecatedConfig` will
|
||||
be raised.
|
||||
|
||||
Otherwise, the message will be logged (once) at the 'warn' level.
|
||||
|
||||
:raises: :class:`DeprecatedConfig` if the system is configured for
|
||||
fatal deprecations.
|
||||
"""
|
||||
stdmsg = _("Deprecated: %s") % msg
|
||||
register_options()
|
||||
if CONF.fatal_deprecations:
|
||||
logger.critical(stdmsg, *args, **kwargs)
|
||||
raise DeprecatedConfig(msg=stdmsg)
|
||||
|
||||
# Using a list because a tuple with dict can't be stored in a set.
|
||||
sent_args = _deprecated_messages_sent.setdefault(msg, list())
|
||||
|
||||
if args in sent_args:
|
||||
# Already logged this message, so don't log it again.
|
||||
return
|
||||
|
||||
sent_args.append(args)
|
||||
logger.warning(stdmsg, *args, **kwargs)
|
||||
|
||||
|
||||
class DeprecatedConfig(Exception):
|
||||
message = _("Fatal call to deprecated config: %(msg)s")
|
||||
|
||||
def __init__(self, msg):
|
||||
super(Exception, self).__init__(self.message % dict(msg=msg))
|
@ -1,111 +0,0 @@
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import errno
|
||||
import logging
|
||||
import logging.config
|
||||
import logging.handlers
|
||||
import os
|
||||
import pyinotify
|
||||
import stat
|
||||
import time
|
||||
try:
|
||||
import syslog
|
||||
except ImportError:
|
||||
syslog = None
|
||||
|
||||
"""Linux specific pyinotify based logging handlers"""
|
||||
|
||||
|
||||
class _FileKeeper(pyinotify.ProcessEvent):
|
||||
def my_init(self, watched_handler, watched_file):
|
||||
self._watched_handler = watched_handler
|
||||
self._watched_file = watched_file
|
||||
|
||||
def process_default(self, event):
|
||||
if event.name == self._watched_file:
|
||||
self._watched_handler.reopen_file()
|
||||
|
||||
|
||||
class _EventletThreadedNotifier(pyinotify.ThreadedNotifier):
|
||||
|
||||
def loop(self):
|
||||
"""Eventlet friendly ThreadedNotifier
|
||||
|
||||
EventletFriendlyThreadedNotifier contains additional time.sleep()
|
||||
call insude loop to allow switching to other thread when eventlet
|
||||
is used.
|
||||
It can be used with eventlet and native threads as well.
|
||||
"""
|
||||
|
||||
while not self._stop_event.is_set():
|
||||
self.process_events()
|
||||
time.sleep(0)
|
||||
ref_time = time.time()
|
||||
if self.check_events():
|
||||
self._sleep(ref_time)
|
||||
self.read_events()
|
||||
|
||||
|
||||
class FastWatchedFileHandler(logging.handlers.WatchedFileHandler, object):
|
||||
"""Frequency of reading events.
|
||||
|
||||
Watching thread sleeps max(0, READ_FREQ - (TIMEOUT / 1000)) seconds.
|
||||
"""
|
||||
READ_FREQ = 5
|
||||
|
||||
"""Poll timeout in milliseconds.
|
||||
|
||||
See https://docs.python.org/2/library/select.html#select.poll.poll"""
|
||||
TIMEOUT = 5
|
||||
|
||||
def __init__(self, logpath, *args, **kwargs):
|
||||
self._log_file = os.path.basename(logpath)
|
||||
self._log_dir = os.path.dirname(logpath)
|
||||
super(FastWatchedFileHandler, self).__init__(logpath, *args, **kwargs)
|
||||
self._watch_file()
|
||||
|
||||
def _watch_file(self):
|
||||
mask = pyinotify.IN_MOVED_FROM | pyinotify.IN_DELETE
|
||||
watch_manager = pyinotify.WatchManager()
|
||||
handler = _FileKeeper(watched_handler=self,
|
||||
watched_file=self._log_file)
|
||||
notifier = _EventletThreadedNotifier(
|
||||
watch_manager,
|
||||
default_proc_fun=handler,
|
||||
read_freq=FastWatchedFileHandler.READ_FREQ,
|
||||
timeout=FastWatchedFileHandler.TIMEOUT)
|
||||
notifier.daemon = True
|
||||
watch_manager.add_watch(self._log_dir, mask)
|
||||
notifier.start()
|
||||
|
||||
def reopen_file(self):
|
||||
try:
|
||||
# stat the file by path, checking for existence
|
||||
sres = os.stat(self.baseFilename)
|
||||
except OSError as err:
|
||||
if err.errno == errno.ENOENT:
|
||||
sres = None
|
||||
else:
|
||||
raise
|
||||
# compare file system stat with that of our stream file handle
|
||||
if (not sres or
|
||||
sres[stat.ST_DEV] != self.dev or
|
||||
sres[stat.ST_INO] != self.ino):
|
||||
if self.stream is not None:
|
||||
# we have an open file handle, clean it up
|
||||
self.stream.flush()
|
||||
self.stream.close()
|
||||
self.stream = None
|
||||
# open a new file handle and get new stat info from that fd
|
||||
self.stream = self._open()
|
||||
self._statstream()
|
@ -1,3 +0,0 @@
|
||||
---
|
||||
other:
|
||||
- Switch to reno for managing release notes.
|
@ -1,4 +0,0 @@
|
||||
---
|
||||
fixes:
|
||||
- When removing the "verbose" option, the default logging level was set to
|
||||
"WARNING" by mistake. Fixed it back to "INFO".
|
@ -1,5 +0,0 @@
|
||||
---
|
||||
features:
|
||||
- The log_config_append configuration option is now mutable and the logging
|
||||
settings it controls are reconfigured when the configuration file is reread.
|
||||
This can be used to, for example, change logger or handler levels.
|
@ -1,3 +0,0 @@
|
||||
---
|
||||
upgrade:
|
||||
- The deprecated log_format configuration option has been removed.
|
@ -1,4 +0,0 @@
|
||||
---
|
||||
upgrade:
|
||||
- The deprecated use_syslog_rfc_format configuration option has been
|
||||
removed.
|
@ -1,274 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# oslo.log Release Notes documentation build configuration file, created by
|
||||
# sphinx-quickstart on Tue Nov 3 17:40:50 2015.
|
||||
#
|
||||
# This file is execfile()d with the current directory set to its
|
||||
# containing dir.
|
||||
#
|
||||
# Note that not all possible configuration values are present in this
|
||||
# autogenerated file.
|
||||
#
|
||||
# All configuration values have a default; values that are commented out
|
||||
# serve to show the default.
|
||||
|
||||
# If extensions (or modules to document with autodoc) are in another directory,
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
# sys.path.insert(0, os.path.abspath('.'))
|
||||
|
||||
# -- General configuration ------------------------------------------------
|
||||
|
||||
# If your documentation needs a minimal Sphinx version, state it here.
|
||||
# needs_sphinx = '1.0'
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be
|
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||
# ones.
|
||||
extensions = [
|
||||
'oslosphinx',
|
||||
'reno.sphinxext',
|
||||
]
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
|
||||
# The suffix of source filenames.
|
||||
source_suffix = '.rst'
|
||||
|
||||
# The encoding of source files.
|
||||
# source_encoding = 'utf-8-sig'
|
||||
|
||||
# The master toctree document.
|
||||
master_doc = 'index'
|
||||
|
||||
# General information about the project.
|
||||
project = u'oslo.log Release Notes'
|
||||
copyright = u'2016, oslo.log Developers'
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
# |version| and |release|, also used in various other places throughout the
|
||||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
from oslo_log.version import version_info as oslo_log_version
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = oslo_log_version.version_string_with_vcs()
|
||||
# The short X.Y version.
|
||||
version = oslo_log_version.canonical_version_string()
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
# language = None
|
||||
|
||||
# There are two options for replacing |today|: either, you set today to some
|
||||
# non-false value, then it is used:
|
||||
# today = ''
|
||||
# Else, today_fmt is used as the format for a strftime call.
|
||||
# today_fmt = '%B %d, %Y'
|
||||
|
||||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
exclude_patterns = []
|
||||
|
||||
# The reST default role (used for this markup: `text`) to use for all
|
||||
# documents.
|
||||
# default_role = None
|
||||
|
||||
# If true, '()' will be appended to :func: etc. cross-reference text.
|
||||
# add_function_parentheses = True
|
||||
|
||||
# If true, the current module name will be prepended to all description
|
||||
# unit titles (such as .. function::).
|
||||
# add_module_names = True
|
||||
|
||||
# If true, sectionauthor and moduleauthor directives will be shown in the
|
||||
# output. They are ignored by default.
|
||||
# show_authors = False
|
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use.
|
||||
pygments_style = 'sphinx'
|
||||
|
||||
# A list of ignored prefixes for module index sorting.
|
||||
# modindex_common_prefix = []
|
||||
|
||||
# If true, keep warnings as "system message" paragraphs in the built documents.
|
||||
# keep_warnings = False
|
||||
|
||||
|
||||
# -- Options for HTML output ----------------------------------------------
|
||||
|
||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||
# a list of builtin themes.
|
||||
html_theme = 'default'
|
||||
|
||||
# Theme options are theme-specific and customize the look and feel of a theme
|
||||
# further. For a list of options available for each theme, see the
|
||||
# documentation.
|
||||
# html_theme_options = {}
|
||||
|
||||
# Add any paths that contain custom themes here, relative to this directory.
|
||||
# html_theme_path = []
|
||||
|
||||
# The name for this set of Sphinx documents. If None, it defaults to
|
||||
# "<project> v<release> documentation".
|
||||
# html_title = None
|
||||
|
||||
# A shorter title for the navigation bar. Default is the same as html_title.
|
||||
# html_short_title = None
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top
|
||||
# of the sidebar.
|
||||
# html_logo = None
|
||||
|
||||
# The name of an image file (within the static path) to use as favicon of the
|
||||
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
||||
# pixels large.
|
||||
# html_favicon = None
|
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
html_static_path = ['_static']
|
||||
|
||||
# Add any extra paths that contain custom files (such as robots.txt or
|
||||
# .htaccess) here, relative to this directory. These files are copied
|
||||
# directly to the root of the documentation.
|
||||
# html_extra_path = []
|
||||
|
||||
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
|
||||
# using the given strftime format.
|
||||
# html_last_updated_fmt = '%b %d, %Y'
|
||||
|
||||
# If true, SmartyPants will be used to convert quotes and dashes to
|
||||
# typographically correct entities.
|
||||
# html_use_smartypants = True
|
||||
|
||||
# Custom sidebar templates, maps document names to template names.
|
||||
# html_sidebars = {}
|
||||
|
||||
# Additional templates that should be rendered to pages, maps page names to
|
||||
# template names.
|
||||
# html_additional_pages = {}
|
||||
|
||||
# If false, no module index is generated.
|
||||
# html_domain_indices = True
|
||||
|
||||
# If false, no index is generated.
|
||||
# html_use_index = True
|
||||
|
||||
# If true, the index is split into individual pages for each letter.
|
||||
# html_split_index = False
|
||||
|
||||
# If true, links to the reST sources are added to the pages.
|
||||
# html_show_sourcelink = True
|
||||
|
||||
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
|
||||
# html_show_sphinx = True
|
||||
|
||||
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
|
||||
# html_show_copyright = True
|
||||
|
||||
# If true, an OpenSearch description file will be output, and all pages will
|
||||
# contain a <link> tag referring to it. The value of this option must be the
|
||||
# base URL from which the finished HTML is served.
|
||||
# html_use_opensearch = ''
|
||||
|
||||
# This is the file name suffix for HTML files (e.g. ".xhtml").
|
||||
# html_file_suffix = None
|
||||
|
||||
# Output file base name for HTML help builder.
|
||||
htmlhelp_basename = 'oslo.logReleaseNotesdoc'
|
||||
|
||||
|
||||
# -- Options for LaTeX output ---------------------------------------------
|
||||
|
||||
latex_elements = {
|
||||
# The paper size ('letterpaper' or 'a4paper').
|
||||
# 'papersize': 'letterpaper',
|
||||
|
||||
# The font size ('10pt', '11pt' or '12pt').
|
||||
# 'pointsize': '10pt',
|
||||
|
||||
# Additional stuff for the LaTeX preamble.
|
||||
# 'preamble': '',
|
||||
}
|
||||
|
||||
# Grouping the document tree into LaTeX files. List of tuples
|
||||
# (source start file, target name, title,
|
||||
# author, documentclass [howto, manual, or own class]).
|
||||
latex_documents = [
|
||||
('index', 'oslo.logReleaseNotes.tex',
|
||||
u'oslo.log Release Notes Documentation',
|
||||
u'oslo.log Developers', 'manual'),
|
||||
]
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top of
|
||||
# the title page.
|
||||
# latex_logo = None
|
||||
|
||||
# For "manual" documents, if this is true, then toplevel headings are parts,
|
||||
# not chapters.
|
||||
# latex_use_parts = False
|
||||
|
||||
# If true, show page references after internal links.
|
||||
# latex_show_pagerefs = False
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
# latex_show_urls = False
|
||||
|
||||
# Documents to append as an appendix to all manuals.
|
||||
# latex_appendices = []
|
||||
|
||||
# If false, no module index is generated.
|
||||
# latex_domain_indices = True
|
||||
|
||||
|
||||
# -- Options for manual page output ---------------------------------------
|
||||
|
||||
# One entry per manual page. List of tuples
|
||||
# (source start file, name, description, authors, manual section).
|
||||
man_pages = [
|
||||
('index', 'oslo.logreleasenotes', u'oslo.log Release Notes Documentation',
|
||||
[u'oslo.log Developers'], 1)
|
||||
]
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
# man_show_urls = False
|
||||
|
||||
|
||||
# -- Options for Texinfo output -------------------------------------------
|
||||
|
||||
# Grouping the document tree into Texinfo files. List of tuples
|
||||
# (source start file, target name, title, author,
|
||||
# dir menu entry, description, category)
|
||||
texinfo_documents = [
|
||||
('index', 'oslo.logReleaseNotes', u'oslo.log Release Notes Documentation',
|
||||
u'oslo.log Developers', 'oslo.logReleaseNotes',
|
||||
'One line description of project.',
|
||||
'Miscellaneous'),
|
||||
]
|
||||
|
||||
# Documents to append as an appendix to all manuals.
|
||||
# texinfo_appendices = []
|
||||
|
||||
# If false, no module index is generated.
|
||||
# texinfo_domain_indices = True
|
||||
|
||||
# How to display URL addresses: 'footnote', 'no', or 'inline'.
|
||||
# texinfo_show_urls = 'footnote'
|
||||
|
||||
# If true, do not generate a @detailmenu in the "Top" node's menu.
|
||||
# texinfo_no_detailmenu = False
|
@ -1,10 +0,0 @@
|
||||
========================
|
||||
oslo.log Release Notes
|
||||
========================
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
unreleased
|
||||
liberty
|
||||
mitaka
|
@ -1,6 +0,0 @@
|
||||
==============================
|
||||
Liberty Series Release Notes
|
||||
==============================
|
||||
|
||||
.. release-notes::
|
||||
:branch: origin/stable/liberty
|
@ -1,63 +0,0 @@
|
||||
# Andi Chandler <andi@gowling.com>, 2016. #zanata
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: oslo.log Release Notes 3.11.1\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2016-07-01 03:32+0000\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"PO-Revision-Date: 2016-06-28 05:55+0000\n"
|
||||
"Last-Translator: Andi Chandler <andi@gowling.com>\n"
|
||||
"Language-Team: English (United Kingdom)\n"
|
||||
"Language: en-GB\n"
|
||||
"X-Generator: Zanata 3.7.3\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
|
||||
|
||||
msgid "3.1.0"
|
||||
msgstr "3.1.0"
|
||||
|
||||
msgid "3.2.0"
|
||||
msgstr "3.2.0"
|
||||
|
||||
msgid "3.8.0"
|
||||
msgstr "3.8.0"
|
||||
|
||||
msgid "Bug Fixes"
|
||||
msgstr "Bug Fixes"
|
||||
|
||||
msgid "Liberty Series Release Notes"
|
||||
msgstr "Liberty Series Release Notes"
|
||||
|
||||
msgid "Mitaka Series Release Notes"
|
||||
msgstr "Mitaka Series Release Notes"
|
||||
|
||||
msgid "Other Notes"
|
||||
msgstr "Other Notes"
|
||||
|
||||
msgid "Switch to reno for managing release notes."
|
||||
msgstr "Switch to reno for managing release notes."
|
||||
|
||||
msgid "The deprecated log_format configuration option has been removed."
|
||||
msgstr "The deprecated log_format configuration option has been removed."
|
||||
|
||||
msgid ""
|
||||
"The deprecated use_syslog_rfc_format configuration option has been removed."
|
||||
msgstr ""
|
||||
"The deprecated use_syslog_rfc_format configuration option has been removed."
|
||||
|
||||
msgid "Unreleased Release Notes"
|
||||
msgstr "Unreleased Release Notes"
|
||||
|
||||
msgid "Upgrade Notes"
|
||||
msgstr "Upgrade Notes"
|
||||
|
||||
msgid ""
|
||||
"When removing the \"verbose\" option, the default logging level was set to "
|
||||
"\"WARNING\" by mistake. Fixed it back to \"INFO\"."
|
||||
msgstr ""
|
||||
"When removing the \"verbose\" option, the default logging level was set to "
|
||||
"\"WARNING\" by mistake. Fixed it back to \"INFO\"."
|
||||
|
||||
msgid "oslo.log Release Notes"
|
||||
msgstr "oslo.log Release Notes"
|
@ -1,6 +0,0 @@
|
||||
===================================
|
||||
Mitaka Series Release Notes
|
||||
===================================
|
||||
|
||||
.. release-notes::
|
||||
:branch: origin/stable/mitaka
|
@ -1,5 +0,0 @@
|
||||
==========================
|
||||
Unreleased Release Notes
|
||||
==========================
|
||||
|
||||
.. release-notes::
|
@ -1,14 +0,0 @@
|
||||
# The order of packages is significant, because pip processes them in the order
|
||||
# of appearance. Changing the order has an impact on the overall integration
|
||||
# process, which may cause wedges in the gate later.
|
||||
|
||||
pbr>=1.6 # Apache-2.0
|
||||
six>=1.9.0 # MIT
|
||||
oslo.config>=3.14.0 # Apache-2.0
|
||||
oslo.context>=2.4.0 # Apache-2.0
|
||||
oslo.i18n>=2.1.0 # Apache-2.0
|
||||
oslo.utils>=3.16.0 # Apache-2.0
|
||||
oslo.serialization>=1.10.0 # Apache-2.0
|
||||
debtcollector>=1.2.0 # Apache-2.0
|
||||
pyinotify>=0.9.6;sys_platform!='win32' and sys_platform!='darwin' and sys_platform!='sunos5' # MIT
|
||||
python-dateutil>=2.4.2 # BSD
|
60
setup.cfg
60
setup.cfg
@ -1,60 +0,0 @@
|
||||
[metadata]
|
||||
name = oslo.log
|
||||
summary = oslo.log library
|
||||
description-file =
|
||||
README.rst
|
||||
author = OpenStack
|
||||
author-email = openstack-dev@lists.openstack.org
|
||||
home-page = http://www.openstack.org
|
||||
classifier =
|
||||
Environment :: OpenStack
|
||||
Intended Audience :: Information Technology
|
||||
Intended Audience :: System Administrators
|
||||
License :: OSI Approved :: Apache Software License
|
||||
Operating System :: POSIX :: Linux
|
||||
Programming Language :: Python
|
||||
Programming Language :: Python :: 2
|
||||
Programming Language :: Python :: 2.7
|
||||
Programming Language :: Python :: 3
|
||||
Programming Language :: Python :: 3.4
|
||||
Programming Language :: Python :: 3.5
|
||||
|
||||
[files]
|
||||
packages =
|
||||
oslo_log
|
||||
|
||||
[extras]
|
||||
fixtures =
|
||||
fixtures>=3.0.0 # Apache-2.0/BSD
|
||||
|
||||
[pbr]
|
||||
warnerrors = true
|
||||
|
||||
[entry_points]
|
||||
oslo.config.opts =
|
||||
oslo.log = oslo_log._options:list_opts
|
||||
|
||||
[build_sphinx]
|
||||
source-dir = doc/source
|
||||
build-dir = doc/build
|
||||
all_files = 1
|
||||
|
||||
[upload_sphinx]
|
||||
upload-dir = doc/build/html
|
||||
|
||||
[compile_catalog]
|
||||
directory = oslo_log/locale
|
||||
domain = oslo_log
|
||||
|
||||
[update_catalog]
|
||||
domain = oslo_log
|
||||
output_dir = oslo_log/locale
|
||||
input_file = oslo_log/locale/oslo_log.pot
|
||||
|
||||
[extract_messages]
|
||||
keywords = _ gettext ngettext l_ lazy_gettext
|
||||
mapping_file = babel.cfg
|
||||
output_file = oslo_log/locale/oslo_log.pot
|
||||
|
||||
[wheel]
|
||||
universal = 1
|
29
setup.py
29
setup.py
@ -1,29 +0,0 @@
|
||||
# Copyright (c) 2013 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# THIS FILE IS MANAGED BY THE GLOBAL REQUIREMENTS REPO - DO NOT EDIT
|
||||
import setuptools
|
||||
|
||||
# In python < 2.7.4, a lazy loading of package `pbr` will break
|
||||
# setuptools if some other modules registered functions in `atexit`.
|
||||
# solution from: http://bugs.python.org/issue15881#msg170215
|
||||
try:
|
||||
import multiprocessing # noqa
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
setuptools.setup(
|
||||
setup_requires=['pbr>=1.8'],
|
||||
pbr=True)
|
@ -1,25 +0,0 @@
|
||||
# The order of packages is significant, because pip processes them in the order
|
||||
# of appearance. Changing the order has an impact on the overall integration
|
||||
# process, which may cause wedges in the gate later.
|
||||
|
||||
hacking<0.11,>=0.10.0
|
||||
|
||||
python-subunit>=0.0.18 # Apache-2.0/BSD
|
||||
testrepository>=0.0.18 # Apache-2.0/BSD
|
||||
testscenarios>=0.4 # Apache-2.0/BSD
|
||||
testtools>=1.4.0 # MIT
|
||||
mock>=2.0 # BSD
|
||||
oslotest>=1.10.0 # Apache-2.0
|
||||
|
||||
# when we can require tox>= 1.4, this can go into tox.ini:
|
||||
# [testenv:cover]
|
||||
# deps = {[testenv]deps} coverage
|
||||
coverage>=3.6 # Apache-2.0
|
||||
|
||||
# this is required for the docs build jobs
|
||||
sphinx!=1.3b1,<1.3,>=1.2.1 # BSD
|
||||
oslosphinx!=3.4.0,>=2.5.0 # Apache-2.0
|
||||
reno>=1.8.0 # Apache2
|
||||
|
||||
# Bandit security code scanner
|
||||
bandit>=1.0.1 # Apache-2.0
|
52
tox.ini
52
tox.ini
@ -1,52 +0,0 @@
|
||||
[tox]
|
||||
minversion = 1.6
|
||||
envlist = py35,py34,py27,pep8
|
||||
|
||||
[testenv]
|
||||
deps = -r{toxinidir}/test-requirements.txt
|
||||
-e.[fixtures]
|
||||
commands =
|
||||
python setup.py test --coverage --coverage-package-name=oslo_log --slowest --testr-args='{posargs}'
|
||||
coverage report --show-missing
|
||||
|
||||
[testenv:pep8]
|
||||
commands =
|
||||
flake8
|
||||
# Run security linter
|
||||
bandit -r oslo_log -x tests -n5
|
||||
|
||||
[testenv:venv]
|
||||
commands = {posargs}
|
||||
|
||||
[testenv:docs]
|
||||
commands = python setup.py build_sphinx
|
||||
|
||||
[testenv:cover]
|
||||
commands =
|
||||
python setup.py test --coverage --coverage-package-name=oslo_log --testr-args='{posargs}'
|
||||
coverage report --show-missing
|
||||
|
||||
[testenv:bandit]
|
||||
commands = bandit -r oslo_log -x tests -n5
|
||||
|
||||
[flake8]
|
||||
# E123, E125 skipped as they are invalid PEP-8.
|
||||
|
||||
show-source = True
|
||||
ignore = E123,E125,H405
|
||||
exclude=.venv,.git,.tox,dist,doc,*lib/python*,*egg,build,__init__.py
|
||||
|
||||
[hacking]
|
||||
import_exceptions = oslo_log._i18n
|
||||
|
||||
[testenv:pip-missing-reqs]
|
||||
# do not install test-requirements as that will pollute the virtualenv for
|
||||
# determining missing packages
|
||||
# this also means that pip-missing-reqs must be installed separately, outside
|
||||
# of the requirements.txt files
|
||||
deps = pip_missing_reqs
|
||||
commands = pip-missing-reqs -d --ignore-module=oslo_log* --ignore-file=oslo_log/tests/* --ignore-file=tests/ oslo_log
|
||||
|
||||
[testenv:releasenotes]
|
||||
commands = sphinx-build -a -E -W -d releasenotes/build/doctrees -b html releasenotes/source releasenotes/build/html
|
||||
|
Loading…
x
Reference in New Issue
Block a user