Remove project content on master branch

This is step 2b of repository deprecation process as described in [1].

[1] https://docs.openstack.org/project-team-guide/repository.html#step-2b-remove-project-content

Change-Id: Ie446c1cd447789d189a9e723fff9ee783dd3cf4f
This commit is contained in:
Martin Chacon Piza 2021-02-22 14:53:29 +01:00
parent f73bff83cb
commit 91022f3e80
190 changed files with 12 additions and 19097 deletions

View File

@ -1,7 +0,0 @@
[run]
branch = True
source = monasca_log_api
omit = monasca_log_api/tests/*
[report]
ignore_errors = True

39
.gitignore vendored
View File

@ -1,39 +0,0 @@
*.py[co]
*~
doc/build/*
dist
build
cover/
.coverage
.coverage.*
*.egg
*.egg-info
.eggs/
.stestr/
.tox/
MANIFEST
AUTHORS
ChangeLog
monasca-log-api.log
etc/monasca/*.sample
*.swp
*.iml
.DS_Store
.cache
.classpath
.idea
.project
.target/
java/debs/*
.settings/
target
test-output/
logs/
*config*.yml
db/config.yml
.venv
.vagrant
# Logs from devstack directory should not be committed
devstack/*.log

View File

@ -1,4 +0,0 @@
[DEFAULT]
test_path=$OS_TEST_PATH
top_dir=./
group_regex=monasca_log_api\.tests(?:\.|_)([^_]+)

View File

@ -1,62 +0,0 @@
- project:
templates:
- check-requirements
- openstack-cover-jobs
- openstack-lower-constraints-jobs
- openstack-python3-victoria-jobs
- publish-openstack-docs-pti
- release-notes-jobs-python3
check:
jobs:
- monasca-tempest-log-oldapi-python3-influxdb
- build-monasca-docker-image
gate:
queue: monasca
jobs:
- monasca-tempest-log-oldapi-python3-influxdb
post:
jobs:
- publish-monasca-log-api-docker-image
periodic:
jobs:
- publish-monasca-log-api-docker-image
release:
jobs:
- publish-monasca-log-api-docker-image
- job:
name: publish-monasca-log-api-docker-image
parent: build-monasca-docker-image
post-run: playbooks/docker-publish.yml
required-projects:
- openstack/monasca-common
vars:
publisher: true
secrets:
- doker_hub_login_log_api
- secret:
name: doker_hub_login_log_api
data:
user: !encrypted/pkcs1-oaep
- mR5DkiEi0lGjpUHgFYlt779KdX0UhPK7+/uJIiawmM5ASJSx90s/DMMDUrPbGc9cpJrOH
zRxBRryUrXuLGpKwQvLAC8uQC3rd9rGrlTVwjszl3nDNFYxKJ3tBMjppG6dBTIo58v6Go
Xo9GdNmaeS3jh6wh9hUqmMlHF4fzaX49GUpZyxTwufA0Y4h/pbq1r7ImbOCLiNUEwxWqH
dPJ9aJMQ5u8qus2r8cs7EHU/KAsFfPEteNtOz3egDSb1/SFYs5oI0VeIs4RvidHe6M56v
vEYx2KjzKKIE4s5TAiU8jU2Qs0RROv+6s7Y23ciqOfFBhVKJg+0PAoge1AwmL6g3FNrW0
sy0uEslPltkbF3Pae9zFe0VU6ZIxYC62kAIBEJj96zc0TIfFYHx4NRbIvkoKopnun7dqF
6hg5k8lZ1kN5RMT2nPNemj9esh0eqCBvLjf4ljy7veYLN9M/GSKSP5A+2chBWFxloWuwB
7PRf9GbDbHA+H+Y6WASK38haHlo9zsoi/D7oJK02LHTwgj4ED3qN34Z9zCVBBr1jN3TUH
9aVOsm+OT1OsUszLQ3BM1HqBZLszrOxuPoqDQ5CURrxEtzrSnX+fsoLyv1tzT/vVnrbAT
/zJxBXGiiE5/3H0isFkK6GUVwsmnLUFYCq5ye6NyLpwdWfTEx6eQDlO5OIE/Qo=
password: !encrypted/pkcs1-oaep
- DALBrHoOI3iZAKArnbPL59d3Mk1OHeDNREq9CJXs601l70AwPmNnK0y1XixbUoAmB8y9C
hkadR+a2s8Lc2+xCzRvr+4tt8vZ+gjgl77WTs43mpb+DfssdP6s5847t6cnE1WKI7GgCS
4as41aOz4HDIdLG6Oe5Jq8HYDx+qcBZhQaeCzObLnbmxdDop6SkpjfziV8+TWxag56joE
V7masPLtYofzQpqB0hRhD3RF7T5fW8uOUlKKzSKhjYuwul1sbOKn6izjufxQs0iimhJpI
HkWCPSj9emr889BfO2DR9/OvTjwSdWZmEtup3RAyWcd6JUESa3oLkG1OFqB0vp6hgx9/F
zFXhBxtEyvs1Odj1ecudr7l+zO4kPVG9cIMHHzd7Tlg1XX2O1/+houVmXd3I1GtxwRYZa
B3Q+yecTLleR1coMM4nZgGtbiky5q6zcttTQCxeUEeCpTUWbxhnLPZyXV+pdFMxsLeUjP
9GcnjuNCgOKHYHyHcXwDoytsqgoTaAS4O+FR5tCmc9dREWsaRCd0dBMy6Xx+ynVJE/1jp
XwtKG/yaFdHyTXwXGQ6ZlW9XnesBejLmetZHx8j7atiMOtKqmM4+N9i0O+1wbl3A2Glxs
K1orRrDJBdLNYVdczq/TUvzl4XBXi+36f1i6auL/WqHUmQy62w1S9WvaqGzEKM=

View File

@ -1,21 +0,0 @@
If you would like to contribute to the development of OpenStack,
you must follow the steps documented at:
http://docs.openstack.org/infra/manual/developers.html#getting-started
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 Storyboard (using tag **bug**), not GitHub:
https://storyboard.openstack.org/#!/project/869
Additionally, specific guidelines for contributing to Monasca-Log-Api may be found in
Monasca-Log-Api's Documentation:
https://docs.openstack.org/monasca-log-api/latest/contributor/

View File

@ -1,5 +0,0 @@
monasca-log-api Style Commandments
==================================
- Step 1: Read the OpenStack Style Commandments https://docs.openstack.org/hacking/latest/
- Step 2: Read on

175
LICENSE
View File

@ -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.

View File

@ -1,193 +0,0 @@
Team and repository tags
========================
[![Team and repository tags](https://governance.openstack.org/badges/monasca-log-api.svg)](https://governance.openstack.org/reference/tags/index.html)
<!-- Change things from this point on -->
# Overview
`monasca-log-api` is a RESTful API server that is designed with a layered architecture [layered architecture](http://en.wikipedia.org/wiki/Multilayered_architecture).
The full API Specification can be found in [documentation/monasca-log-api-spec.md](documentation/monasca-log-api-spec.md)
## Monasca-log-api Python
### Installation
To install the python api implementation, git clone the source and run the
following command:
```sh
sudo python setup.py install
```
### Configuration
If it installs successfully, you will need to make changes to the following
two files to reflect your system settings, especially where kafka server is
located::
```sh
/etc/monasca/log-api-config.conf
/etc/monasca/log-api-config.ini
/etc/monasca/log-api-logging.conf
```
Once the configurations are modified to match your environment, you can start
up the server using either Gunicorn or Apache.
### Start the Server -- for Gunicorn
The server can be run in the foreground, or as daemons:
Running the server in foreground mode with Gunicorn:
```sh
gunicorn -k eventlet --worker-connections=2000 --backlog=1000
--paste /etc/monasca/log-api-config.ini
```
Running the server as daemons with Gunicorn:
```sh
gunicorn -k eventlet --worker-connections=2000 --backlog=1000
--paste /etc/monasca/log-api-config.ini -D
```
### Start the Server -- for Apache
To start the server using Apache: create a modwsgi file,
create a modwsgi config file, and enable the wsgi module
in Apache.
The modwsgi conf file may look something like this, and the site will need to be enabled:
```sh
Listen myhost:8082
Listen 127.0.0.1:8082
<VirtualHost *:8082>
WSGIDaemonProcess log-api processes=4 threads=4 socket-timeout=120 user=log group=log python-path=/usr/local/lib/python2.7/site-packages
WSGIProcessGroup log-api
WSGIApplicationGroup log-api
WSGIScriptAlias / /var/www/log/log-api.wsgi
ErrorLog /var/log/log-api/wsgi.log
LogLevel info
CustomLog /var/log/log-api/wsgi-access.log combined
<Directory /usr/local/lib/python2.7/site-packages/monasca_log_api>
Options Indexes FollowSymLinks MultiViews
Require all granted
AllowOverride None
Order allow,deny
allow from all
LimitRequestBody 102400
</Directory>
SetEnv no-gzip 1
</VirtualHost>
```
The wsgi file may look something like this:
```sh
from monasca_log_api.server import get_wsgi_app
application = get_wsgi_app(config_base_path='/etc/monasca')
```
## Testing
### Commandline run
To check the server from the commandline:
```sh
python server.py
```
### PEP8 guidelines
To check if the code follows python coding style, run the following command
from the root directory of this project:
```sh
tox -e pep8
```
### Unit Tests
To run all the unit test cases, run the following command from the root
directory of this project:
```sh
tox -e py27
tox -e py35
```
### Coverage
To generate coverage results, run the following command from the root
directory of this project:
```sh
tox -e cover
```
### Building
To build an installable package, run the following command from the root
directory of this project:
```sh
python setup.py sdist
```
### Documentation
To generate documentation, run the following command from the root
directory of this project:
```sh
tox -e docs
```
That will create documentation under build folder relative to root of the
project.
## Architectural layers
Requests flow through the following architectural layers from top to bottom:
* Resource
* Serves as the entrypoint into the service.
* Responsible for handling web service requests, and performing structural request validation.
* Application
* Responsible for providing application level implementations for specific use cases.
* Domain
* Contains the technology agnostic core domain model and domain service definitions.
* Responsible for upholding invariants and defining state transitions.
* Infrastructure
* Contains technology specific implementations of domain services.
## Documentation
* API Specification: [/documentation/monasca-log-api-spec.md](/documentation/monasca-log-api-spec.md).
* Kafka communication: [/documentation/monasca-log-api-kafka.md](/documentation/monasca-log-api-kafka.md).
* API Monitoring: [/documentation/monasca-log-api-metrics.md](/documentation/monasca-log-api-metrics.md).
# License
# Copyright 2015 kornicameister@gmail.com
# Copyright 2015-2017 FUJITSU LIMITED
#
# 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.

View File

@ -1,73 +1,17 @@
========================
Team and repository tags
========================
.. image:: https://governance.openstack.org/tc/badges/monasca-log-api.svg
:target: https://governance.openstack.org/tc/reference/tags/index.html
.. Change things from this point on
OpenStack Monasca-Log-Api
=========================
.. important::
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".
This API is deprecated. Last maintained release is OpenStack Train.
Please use `Monasca API <https://docs.openstack.org/monasca-api/latest/>`_
for newer versions. This repository is kept only for maintenance purposes.
This API is deprecated. Last maintained release is OpenStack Train.
Please use `Monasca API <https://docs.openstack.org/monasca-api/latest/>`_
for newer versions. This repository is kept only for maintenance purposes.
OpenStack Monasca-Log-Api provides RESTful Api to collect logs
from the OpenStack cloud.
OpenStack Monasca-Log-Api is distributed under the terms of the Apache
License, Version 2.0. The full terms and conditions of this
license are detailed in the LICENSE file.
Api
---
To learn how to use Monasca-Log-Api, consult the documentation
available online at:
* `Api Guide <https://docs.openstack.org/api-guide/monitoring-log-api/>`_
* `Api Ref <https://docs.openstack.org/api-ref/monitoring-log-api/>`_
For more information on OpenStack Apis, SDKs and CLIs,
please see:
* `OpenStack Application Development <https://www.openstack.org/appdev/>`_
* `OpenStack Developer Documentation <https://developer.openstack.org/>`_
Developers
----------
For information on how to contribute to Monasca-Log-Api, please see the
contents of the CONTRIBUTING.rst.
Any new code must follow the development guidelines detailed
in the HACKING.rst file, and pass all unit tests as well as linters.
Further developer focused documentation is available at:
* `Monasca-Log-Api <https://docs.openstack.org/monasca-log-api/latest/>`_
Operators
---------
To learn how to deploy and configure OpenStack Monasca-Log-Api, consult the
documentation available online at:
* `Installation <https://docs.openstack.org/monasca-log-api/latest/install/>`_
* `Configuration <https://docs.openstack.org/monasca-log-api/latest/configuration/>`_
Bug tracking
------------
In the unfortunate event that bugs are discovered, they should
be reported to the appropriate bug tracker. If you obtained
the software from a 3rd party operating system vendor, it is
often wise to use their own bug tracker for reporting problems.
In all other cases use the master OpenStack bug tracker,
available at:
* `Storyboard <https://storyboard.openstack.org/#!/project/869>`_
For any further questions, please email
openstack-discuss@lists.openstack.org or join #openstack-monasca on
Freenode.

View File

@ -1,252 +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.
#
# Key Manager API documentation build configuration file
#
# All configuration values have a default; values that are commented out
# serve to show the default.
# -- General configuration ------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
needs_sphinx = '1.6'
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'openstackdocstheme'
]
# 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'
# The master toctree document.
master_doc = 'index'
# General details about project
openstackdocs_repo_name = 'openstack/monasca-log-api'
openstackdocs_auto_name = False
project = 'Monasca Log API Guide'
openstackdocs_bug_project = 'monasca-log-api'
openstackdocs_bug_tag = 'api-guide'
copyright = '2014, OpenStack Foundation'
# 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 = 'native'
# 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 = 'openstackdocs'
# 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 = {}
# A shorter title for the navigation bar. Default is the same as html_title.
html_short_title = 'API Guide'
# 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 = []
# 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 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 = 'monascalogapi-api-guide'
# -- 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', 'MonascaLogApiAPI.tex', u'Key Manager API Documentation',
u'OpenStack Foundation', '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', 'monascalogapiapi', u'Monasca Log API Documentation',
[u'OpenStack Foundation'], 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', 'MonascaLogApiAPIGuide', u'Monasca Log API Guide',
u'OpenStack Foundation', 'APIGuide',
'This guide teaches OpenStack Monasca Log service users concepts about '
'managing keys in an OpenStack cloud with the Monasca Log API.',
'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
# -- Options for Internationalization output ------------------------------
locale_dirs = ['locale/']
# -- Options for PDF output --------------------------------------------------
pdf_documents = [
('index', u'MonascaLogApiAPIGuide', u'Key Manager API Guide', u'OpenStack '
'contributors')
]

View File

@ -1,50 +0,0 @@
..
Copyright 2014-2017 Fujitsu LIMITED
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.
========================
Monasca Log API Concepts
========================
The Monasca Log API is defined as a RESTful HTTP service. The API
takes advantage of all aspects of the HTTP protocol (methods, URIs,
media types, response codes, etc.) and providers are free to use
existing features of the protocol such as caching, persistent
connections, and content compression among others.
Providers can return information identifying requests in HTTP response
headers, for example, to facilitate communication between the provider
and client applications.
Monasca LOG is a service that provides log collection capabilities over cloud.
User Concepts
=============
To use the Monasca Log API effectively, you should understand several
key concepts:
- **Log**
- **Dimensions**
Relationship with Metric API
============================
The Monasca Log API follow similar concept as Monasca Metric API.
Both are using the same meta-like language to describie entities that are
sent over wire. Below list enumerates those meta properties:
- dimensions
- meta_value

View File

@ -1,70 +0,0 @@
..
Copyright 2014-2017 Fujitsu LIMITED
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.
===============
Monasca Log API
===============
The monasca-log-api project has a RESTful HTTP service called the
Monasca Log API. Through this API users are able to send logs from entire
cloud.
This guide covers the concepts in the Monasca Log API.
For a full reference listing, please see:
`Monasca Log API Reference <https://docs.openstack.org/api-ref/monitoring-log-api/>`__.
We welcome feedback, comments, and bug reports at
`storyboard/monasca <https://storyboard.openstack.org/#!/project_group/59>`__.
Intended audience
=================
This guide assists software developers who want to develop applications
using the Monasca Log API. To use this information, you should
have access to an account from an OpenStack Compute provider, or have
access to your own deployment, and you should also be familiar with the
following concepts:
* Monasca services
* RESTful HTTP services
* HTTP/1.1
* JSON data serialization formats
End User and Operator APIs
==========================
The Log API includes all end user and operator API calls.
The API works with keystone and, at the monent, uses custom RBAC to
enforce API security.
API Versions
============
Following the Newton release, every Nova deployment should have
the following endpoints:
* / - list of available versions
* /v2.0 - the first version, permitted only single log to be send per request
* /v3.0 - the next version, allows sending multiple logs at once
Contents
========
.. toctree::
:maxdepth: 2
general_info
logs

View File

@ -1,18 +0,0 @@
..
Copyright 2014-2017 Fujitsu LIMITED
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.
====
Logs
====

View File

@ -1,247 +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.
#
# Key Manager API documentation build configuration file
#
# All configuration values have a default; values that are commented out
# serve to show the default.
# -- General configuration ------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
needs_sphinx = '1.6'
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'os_api_ref',
'openstackdocstheme'
]
# 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'
# The master toctree document.
master_doc = 'index'
# General details about project
openstackdocs_repo_name = 'openstack/monasca-log-api'
openstackdocs_auto_name = False
project = 'Monasca Log Ref Guide'
openstackdocs_bug_project = 'monasca-log-api'
openstackdocs_bug_tag = 'api-ref'
copyright = '2014, OpenStack Foundation'
# 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 = 'native'
# 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 = 'openstackdocs'
# To use the API Reference sidebar dropdown menu,
# uncomment the html_theme_options parameter. The theme
# variable, sidebar_dropdown, should be set to `api_ref`.
# Otherwise, the list of links for the User and Ops docs
# appear in the sidebar dropdown menu.
html_theme_options = {"sidebar_dropdown": "api_ref",
"sidebar_mode": "toc"}
# A shorter title for the navigation bar. Default is the same as html_title.
html_short_title = 'API Ref'
# 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 = []
# 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 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 = 'monascalogapi-api-ref'
# -- 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 = [
(master_doc, 'MonascaLogApi.tex', u'Monasca Log API Documentation',
u'OpenStack Foundation', '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 = [
(master_doc, 'monascalogapi', u'Monasca Log API Documentation',
[u'OpenStack Foundation'], 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 = [
(master_doc, 'MonascaLogAPI', u'Monasca Log API Documentation',
u'OpenStack Foundation', 'MonascaLogAPI', 'Monasca Log API',
'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
# -- Options for Internationalization output ------------------------------
locale_dirs = ['locale/']

View File

@ -1,54 +0,0 @@
.. -*- rst -*-
..
Copyright 2017 Fujitsu LIMITED
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.
===========
Healthcheck
===========
The *Monasca Log API* comes with a built-in health check mechanism.
It is available in two flavors (simple and complex).
Simple check
============
The simple check only returns response only if API is up
and running. It does not return any data because it is accessible only
for ```HEAD``` requests.
.. rest_method:: HEAD /healthcheck
.. rest_status_code:: success http_codes.yaml
- 204: la_up
Complex check
=============
# TODO(trebskit) add note to api-guide about peripheral checks
The complex check not only returns a response with success code if API
is up and running but it also verifies if peripheral components are
in expected condition.
.. rest_method:: GET /healthcheck
.. rest_status_code:: success http_codes.yaml
- 200: la_up
.. rest_status_code:: error http_codes.yaml
- 503: no_health

View File

@ -1,56 +0,0 @@
# Copyright 2017 Fujitsu LIMITED
200:
la_up: |
API is up and running.
204:
default: |
Normal response code, everything went as expected (or even better).
la_up: |
API is up and running.
400:
default: |
Sent data was malformed.
401:
default: |
User must authenticate before making a request.
403:
default: |
Policy does not allow current user to do this operation.
411:
default: |
Content-Length header was not found in request.
413:
default: |
Sent body is too large to be processed.
422:
default: |
Send data could not be processed properly.
no_dims: |
Dimensions are required.
dim_name_too_long: |
Dimension name {name} must be 255 characters or less.
dim_name_underscore: |
Dimension name {name} cannot start with underscore (_).
dim_name_forbidden_chars: |
Dimension name {name} may not contain: "> < = { } ( ) \' " , ; &".
dim_name_empty: |
Dimension name cannot be empty.
dim_value_too_long: |
Dimension value {value} must be 255 characters or less.
dim_value_empty: |
Dimension value cannot be empty.
app_type_too_long: |
Application type {type} must be {length} characters or less.
log_no_msg: |
Log property must have message.
bad_envelope: |
Failed to create an envelope.
503:
default: |
The server is currently unable to handle the request due to a
temporary overload or scheduled maintenance.
This will likely be alleviated after some delay.
no_health:
API is running but there are problems with peripheral components.

View File

@ -1,35 +0,0 @@
:tocdepth: 2
..
Copyright 2014-2017 Fujitsu LIMITED
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.
========================
Monasca Log Service APIs
========================
.. rest_expand_all::
.. include:: logs.inc
.. include:: version.inc
.. include:: healthcheck.inc
===============
Deprecated APIs
===============
This section contains the reference for APIs that are
depracted in the Monasca Log Service
.. include:: log.inc

View File

@ -1,73 +0,0 @@
.. -*- rst -*-
..
Copyright 2017 Fujitsu LIMITED
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
====
Accepts just a single log entry sent from log-agent of another client.
Can work with logs specified as json (application/json) and text (text/plain)
Send logs
=========
.. rest_method:: POST /v2.0/log/single
Accepts single log entry.
.. rest_status_code:: success http_codes.yaml
- 204
.. rest_status_code:: error http_codes.yaml
- 422: no_dims
- 422: app_type_too_long
- 422: dim_name_too_long
- 422: dim_name_underscore
- 422: dim_name_forbidden_chars
- 422: dim_name_empty
- 422: dim_value_too_long
- 422: dim_value_empty
- 422: log_no_msg
- 422: bad_envelope
- 503
Request
-------
.. rest_parameters:: parameters.yaml
- log_json: log_json
- log_text: log_text
- X_Dimensions: X_Dimensions
- X_Application_Type: X_Application_Type
**Example 1: Simple request with single log (json)**
.. literalinclude:: ../../doc/api_samples/v2/req_json.json
:language: javascript
**Example 2: Simple request with single log (text)**
.. literalinclude:: ../../doc/api_samples/v2/req_text.txt
:language: text
Response
--------
No body content is returned on a successful POST

View File

@ -1,75 +0,0 @@
.. -*- rst -*-
..
Copyright 2017 Fujitsu LIMITED
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.
====
Logs
====
Accepts logs send from log-agents. Logs are basically raw lines,
as collected from physical resources, enriched with dimensions.
Send logs
=========
.. rest_method:: POST /v3.0/logs
Accepts multiple logs (i.e. bulk mode). Each log can be enriched with set
of dimensions. If necessary some of the dimensions can be specified as global
dimensions (that is particularly useful, to make request smaller,
if there is a lot of duplicates among each log entry dimensions)
.. rest_status_code:: success http_codes.yaml
- 204
.. rest_status_code:: error http_codes.yaml
- 400
- 401
- 403
- 411
- 413
- 422: log_no_msg
- 422: bad_envelope
- 503
Request
-------
.. rest_parameters:: parameters.yaml
- dimensions: dimensions
- logs: logs
**Example 1: Simple request with single log**
.. literalinclude:: ../../doc/api_samples/v3/req_single_log.json
:language: javascript
**Example 2: Send multiple logs at once**
.. literalinclude:: ../../doc/api_samples/v3/req_multiple_logs.json
:language: javascript
**Example 3: Specify global dimensions for each log entry**
.. literalinclude:: ../../doc/api_samples/v3/req_global_dims.json
:language: javascript
Response
--------
No body content is returned on a successful POST

View File

@ -1,50 +0,0 @@
# Copyright 2017 Fujitsu LIMITED
# header params
X_Application_Type:
description: |
A single string value representing the application that has generated
given log entry
in: header
required: true
required: true
type: string
min_version: 2.0
X_Dimensions:
description: |
A dictionary consisting of (key, value) pairs used to uniquely
identify a log.
in: header
required: true
type: dict
min_version: 2.0
# body params
dimensions:
description: |
Dimensions sent in request body are known as global dimensions.
Each dimension applies to each log entry sent in a bulk request.
Dimensions are simple map (thus having key-value structure).
in: body
required: false
type: object
min_version: 3.0
log_json:
description: |
Single log entry specified as application/json
in: body
required: true
type: object
log_text:
description: |
Single log entry specified as text/plain
in: body
required: true
type: string
logs:
description: |
Array containing each log entry, sent in bulk request.
in: body
required: true
type: object
min_version: 3.0

View File

@ -1,19 +0,0 @@
.. -*- rst -*-
..
Copyright 2017 Fujitsu LIMITED
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.
=======
Version
=======

View File

@ -1,13 +0,0 @@
# config-generator
To generate sample configuration execute
```sh
tox -e genconfig
```
To generate the sample policies execute
```sh
tox -e genpolicy
```

View File

@ -1,8 +0,0 @@
[DEFAULT]
output_file = etc/monasca/monasca-log-api.conf.sample
wrap_width = 79
format = ini
summarize = True
namespace = monasca_log_api
namespace = oslo.log
namespace = oslo.policy

View File

@ -1,4 +0,0 @@
[DEFAULT]
output_file = etc/monasca/log-api.policy.yaml.sample
format = yaml
namespace = monasca_log_api

View File

@ -1,103 +0,0 @@
#
# (C) Copyright 2015 Hewlett Packard Enterprise Development Company LP
# (C) Copyright 2016-2017 FUJITSU LIMITED
#
# 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.
# Sleep some time until all services are starting
sleep 6
function load_devstack_utilities {
source $BASE/new/devstack/stackrc
source $BASE/new/devstack/functions
source $BASE/new/devstack/openrc admin admin
# print OS_ variables
env | grep OS_
}
function setup_monasca_log {
local constraints="-c $REQUIREMENTS_DIR/upper-constraints.txt"
pushd $TEMPEST_DIR
sudo -EH pip install $constraints -r requirements.txt -r test-requirements.txt
popd;
pushd $MONASCA_LOG_API_DIR
sudo -EH pip install $constraints -r requirements.txt -r test-requirements.txt
sudo -EH python setup.py install
popd;
}
function set_tempest_conf {
local conf_file=$TEMPEST_DIR/etc/tempest.conf
pushd $TEMPEST_DIR
oslo-config-generator \
--config-file tempest/cmd/config-generator.tempest.conf \
--output-file $conf_file
popd
cp -f $DEST/tempest/etc/logging.conf.sample $DEST/tempest/etc/logging.conf
# set identity section
iniset $conf_file identity admin_domain_scope True
iniset $conf_file identity user_unique_last_password_count 2
iniset $conf_file identity user_locakout_duration 5
iniset $conf_file identity user_lockout_failure_attempts 2
iniset $conf_file identity uri $OS_AUTH_URL/v2.0
iniset $conf_file identity uri_v3 $OS_AUTH_URL/v3
iniset $conf_file identity auth_version v$OS_IDENTITY_API_VERSION
iniset $conf_file identity region $OS_REGION_NAME
# NOTE(trebskit) we're processing a lot here, increase http timeout
iniset $conf_file identity-feature-enabled http_timeout 120
# set auth section
iniset $conf_file auth use_dynamic_credentials True
iniset $conf_file auth admin_username $OS_USERNAME
iniset $conf_file auth admin_password $OS_PASSWORD
iniset $conf_file auth admin_domain_name $OS_PROJECT_DOMAIN_ID
iniset $conf_file auth admin_project_name $OS_PROJECT_NAME
iniset $conf_file auth tempest_roles monasca-user
# set monitoring section
iniset $conf_file monitoring kibana_version 4.6.3
}
function function_exists {
declare -f -F $1 > /dev/null
}
if ! function_exists echo_summary; then
function echo_summary {
echo $@
}
fi
echo_summary "monasca-log's post_test_hook.sh was called..."
(set -o posix; set)
# save ref to monasca-api dir
export MONASCA_LOG_API_DIR="$BASE/new/monasca-log-api"
export TEMPEST_DIR="$BASE/new/tempest"
sudo chown -R "${USER}":stack $MONASCA_LOG_API_DIR
sudo chown -R "${USER}":stack $TEMPEST_DIR
load_devstack_utilities
setup_monasca_log
set_tempest_conf

View File

@ -1,119 +0,0 @@
# Monasca Log Management DevStack Plugin
The Monasca Log Management DevStack plugin currently only works on Ubuntu 14.04 (Trusty).
More Linux Distributions will be supported in the future.
Monasca Log Management Devstack plugin requires Monasca Devstack plugin.
Running the Monasca DevStack plugin and Monasca Log Management Devstack plugin requires a machine with 14GB of RAM.
Directions for installing and running Devstack can be found here:
```
https://docs.openstack.org/devstack/latest/
```
To run Monasca Log Management in DevStack, do the following three steps.
1. Clone the DevStack repo.
```
git clone https://opendev.org/openstack/devstack
```
2. Add the following to the DevStack local.conf file in the root of the devstack directory. You may
need to create the local.conf if it does not already exist.
```
[[local|localrc]]
MYSQL_PASSWORD=secretmysql
DATABASE_PASSWORD=secretdatabase
RABBIT_PASSWORD=secretrabbit
ADMIN_PASSWORD=secretadmin
SERVICE_PASSWORD=secretservice
SERVICE_TOKEN=111222333444
LOGFILE=$DEST/logs/stack.sh.log
LOGDIR=$DEST/logs
LOG_COLOR=False
# The following two variables allow switching between Java and Python for the implementations
# of the Monasca API and the Monasca Persister. If these variables are not set, then the
# default is to install the Python implementations of both the Monasca API and the Monasca Persister.
# Uncomment one of the following two lines to choose Java or Python for the Monasca API.
MONASCA_API_IMPLEMENTATION_LANG=${MONASCA_API_IMPLEMENTATION_LANG:-java}
# MONASCA_API_IMPLEMENTATION_LANG=${MONASCA_API_IMPLEMENTATION_LANG:-python}
# Uncomment of the following two lines to choose Java or Python for the Monasca Pesister.
MONASCA_PERSISTER_IMPLEMENTATION_LANG=${MONASCA_PERSISTER_IMPLEMENTATION_LANG:-java}
# MONASCA_PERSISTER_IMPLEMENTATION_LANG=${MONASCA_PERSISTER_IMPLEMENTATION_LANG:-python}
# Uncomment one of the following two lines to choose either InfluxDB or Vertica.
MONASCA_METRICS_DB=${MONASCA_METRICS_DB:-influxdb}
# MONASCA_METRICS_DB=${MONASCA_METRICS_DB:-vertica}
# This line will enable all of Monasca.
enable_plugin monasca-api https://opendev.org/openstack/monasca-api
enable_plugin monasca-log-api https://opendev.org/openstack/monasca-log-api.git
```
3. Run './stack.sh' from the root of the devstack directory.
After finishing the installation, you can find the "Log Management" button on
"Overview" of "Monitoring" tab, if you log in OpenStack as admin.
At first time, you need to specify the index pattern and time-field name.
The index name is created as the following format.
logs-\[mini-mon tenant id\]-YYYY-MM-DD
For example:
logs-20c4fbd37a2345dd84266dfc92da7bd1-2016-04-07
Set the value as the above to index pattern.
Or you can use "\*" as a wild card, like below.
logs-20c4fbd37a2345dd84266dfc92da7bd1-\*
Select @timestamp as time-field name.
4. Extra settings
## Using WSGI
monasca-log-api can be deployed with Apache using mod_uwsgi.
By default monasca-log-api by default runs under gunicorn.
If you wish to use Apache make sure that ```devstack/local.conf```
contains:
```sh
MONASCA_LOG_API_USE_MOD_WSGI=True
```
Actual ```MONASCA_LOG_API_DEPLOY``` value is determined using devstack`s
```WSGI_MODE``` variable. Nevertheless there are only three possible values,
that ```MONASCA_LOG_API_DEPLOY``` can take:
* ```gunicorn``` if ```MONASCA_LOG_API_USE_MOD_WSGI=False```
* ```mod_wsgi``` if ```MONASCA_LOG_API_USE_MOD_WSGI=True && WSGI_MODE="mod_wsgi""```
* ```uwsgi``` if ```MONASCA_LOG_API_USE_MOD_WSGI=True && WSGI_MODE="uwsgi""```
# Using Vagrant
Vagrant can be used to deploy a VM with Devstack and Monasca Logging
running in it using the Vagrantfile. After installing Vagrant,
just run the command `vagrant up` as usual in the `monasca-log-api/devstack`
directory.
```
# Copyright 2016 FUJITSU LIMITED
#
# 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.
```

123
devstack/Vagrantfile vendored
View File

@ -1,123 +0,0 @@
require 'vagrant.rb'
Vagrant.configure(2) do |config|
config.cache.scope = :box if Vagrant.has_plugin?("vagrant-cachier")
config.timezone.value = :host if Vagrant.has_plugin?('vagrant-timezone')
if Vagrant.has_plugin?('vagrant-proxyconf')
config.proxy.http = ENV['http_proxy'] if ENV['http_proxy']
config.proxy.https = ENV['https_proxy'] if ENV['https_proxy']
if ENV['no_proxy']
local_no_proxy = ",192.168.10.6,10.0.2.15"
config.proxy.no_proxy = ENV['no_proxy'] + local_no_proxy
end
end
config.ssh.forward_agent = true
config.vm.hostname = "devstack"
config.vm.box = "bento/ubuntu-18.04"
config.vm.network "private_network",ip:"192.168.10.6"
config.vm.synced_folder "~/", "/vagrant_home"
config.vm.provider "virtualbox" do |vb|
vb.gui = false
vb.memory = "12800"
vb.cpus = 4
end
config.vm.provision "shell", privileged: false, inline: <<-SHELL
sudo apt-get -y install git
if [ $http_proxy ]; then
git config --global url.https://opendev.org/.insteadOf https://opendev.org/
sudo git config --global url.https://opendev.org/.insteadOf https://opendev.org/
protocol=`echo $http_proxy | awk -F: '{print $1}'`
host=`echo $http_proxy | awk -F/ '{print $3}' | awk -F: '{print $1}'`
port=`echo $http_proxy | awk -F/ '{print $3}' | awk -F: '{print $2}'`
echo "<settings>
<proxies>
<proxy>
<id>$host</id>
<active>true</active>
<protocol>$protocol</protocol>
<host>$host</host>
<port>$port</port>
</proxy>
</proxies>
</settings>" > ./maven_proxy_settings.xml
mkdir ~/.m2
cp ./maven_proxy_settings.xml ~/.m2/settings.xml
sudo mkdir /root/.m2
sudo cp ./maven_proxy_settings.xml /root/.m2/settings.xml
fi
git clone https://opendev.org/openstack/devstack --branch master --depth 1
cd devstack
echo '[[local|localrc]]
GIT_DEPTH=1
DEST=/opt/stack
USE_VENV=False
SERVICE_HOST=192.168.10.6
HOST_IP=192.168.10.6
DATABASE_HOST=192.168.10.6
MYSQL_HOST=192.168.10.6
HOST_IP_IFACE=eth1
MYSQL_PASSWORD=secretmysql
DATABASE_PASSWORD=secretdatabase
RABBIT_PASSWORD=secretrabbit
ADMIN_PASSWORD=secretadmin
SERVICE_PASSWORD=secretservice
LOGFILE=$DEST/logs/stack.sh.log
LOGDIR=$DEST/logs
LOG_COLOR=False
disable_all_services
enable_service zookeeper rabbit mysql key tempest horizon
# Enable more OpenStack services if neccessary:
# https://github.com/openstack-dev/devstack/blob/master/stackrc#L56-L81
# Nova - services to support libvirt based openstack clouds
# enable_service n-api n-cpu n-cond n-sch n-novnc n-cauth n-api-meta
# Placement and Glance services needed for Nova
# enable_service placement-api placement-client
# enable_service g-api g-reg
# Cinder, Neutron
# enable_service cinder c-api c-vol c-sch c-bak
# enable_service neutron q-svc q-agt q-dhcp q-meta q-l3
# The following two variables allow switching between Java and Python for the implementations
# of the Monasca API and the Monasca Persister. If these variables are not set, then the
# default is to install the Python implementations of both the Monasca API and the Monasca Persister.
# Uncomment one of the following two lines to choose Java or Python for the Monasca API.
# MONASCA_API_IMPLEMENTATION_LANG=${MONASCA_API_IMPLEMENTATION_LANG:-java}
MONASCA_API_IMPLEMENTATION_LANG=${MONASCA_API_IMPLEMENTATION_LANG:-python}
# Uncomment one of the following two lines to choose Java or Python for the Monasca Pesister.
# MONASCA_PERSISTER_IMPLEMENTATION_LANG=${MONASCA_PERSISTER_IMPLEMENTATION_LANG:-java}
MONASCA_PERSISTER_IMPLEMENTATION_LANG=${MONASCA_PERSISTER_IMPLEMENTATION_LANG:-python}
# Uncomment one of the following two lines to choose either InfluxDB or Vertica.
# MONASCA_METRICS_DB=${MONASCA_METRICS_DB:-vertica}
# MONASCA_METRICS_DB=${MONASCA_METRICS_DB:-cassandra}
MONASCA_METRICS_DB=${MONASCA_METRICS_DB:-influxdb}
# Uncomment following line to deploy monasca-log-api with Apache
# MONASCA_LOG_API_USE_MOD_WSGI=True
# Uncomment one of the following lines and modify accordingly to enable the Monasca DevStack Plugin
enable_plugin monasca-api https://opendev.org/openstack/monasca-api.git
enable_plugin monasca-log-api https://opendev.org/openstack/monasca-log-api.git
' > local.conf
./stack.sh
SHELL
end

View File

@ -1,25 +0,0 @@
Listen %PUBLICPORT%
<VirtualHost *:%PUBLICPORT%>
WSGIDaemonProcess monasca-log-api processes=%APIWORKERS% threads=1 user=%USER% display-name=%{GROUP} %VIRTUALENV%
WSGIProcessGroup monasca-log-api
WSGIScriptAlias / %PUBLICWSGI%
WSGIApplicationGroup %{GLOBAL}
WSGIPassAuthorization On
<IfVersion >= 2.4>
ErrorLogFormat "%M"
</IfVersion>
ErrorLog /var/log/%APACHE_NAME%/monasca-log-api.log
%SSLENGINE%
%SSLCERTFILE%
%SSLKEYFILE%
</VirtualHost>
Alias /logs %PUBLICWSGI%
<Location /logs>
SetHandler wsgi-script
Options +ExecCGI
WSGIProcessGroup monasca-log-api
WSGIApplicationGroup %{GLOBAL}
WSGIPassAuthorization On
</Location>

View File

@ -1,360 +0,0 @@
##################### Elasticsearch Configuration Example #####################
# This file contains an overview of various configuration settings,
# targeted at operations staff. Application developers should
# consult the guide at <http://elasticsearch.org/guide>.
#
# The installation procedure is covered at
# <http://elasticsearch.org/guide/en/elasticsearch/reference/current/setup.html>.
#
# Elasticsearch comes with reasonable defaults for most settings,
# so you can try it out without bothering with configuration.
#
# Most of the time, these defaults are just fine for running a production
# cluster. If you're fine-tuning your cluster, or wondering about the
# effect of certain configuration option, please _do ask_ on the
# mailing list or IRC channel [http://elasticsearch.org/community].
# Any element in the configuration can be replaced with environment variables
# by placing them in ${...} notation. For example:
#
#node.rack: ${RACK_ENV_VAR}
# For information on supported formats and syntax for the config file, see
# <http://elasticsearch.org/guide/en/elasticsearch/reference/current/setup-configuration.html>
################################### Cluster ###################################
# Cluster name identifies your cluster for auto-discovery. If you're running
# multiple clusters on the same network, make sure you're using unique names.
#
cluster.name: monasca_elastic
#################################### Node #####################################
# Node names are generated dynamically on startup, so you're relieved
# from configuring them manually. You can tie this node to a specific name:
#
node.name: "devstack"
# Allow this node to be eligible as a master node (enabled by default):
node.master: true
# Allow this node to store data (enabled by default)
node.data: true
# You can exploit these settings to design advanced cluster topologies.
#
# 1. You want this node to never become a master node, only to hold data.
# This will be the "workhorse" of your cluster.
#
#node.master: false
#node.data: true
#
# 2. You want this node to only serve as a master: to not store any data and
# to have free resources. This will be the "coordinator" of your cluster.
#
#node.master: true
#node.data: false
#
# 3. You want this node to be neither master nor data node, but
# to act as a "search load balancer" (fetching data from nodes,
# aggregating results, etc.)
#
#node.master: false
#node.data: false
# Use the Cluster Health API [http://localhost:9200/_cluster/health], the
# Node Info API [http://localhost:9200/_nodes] or GUI tools
# such as <http://www.elasticsearch.org/overview/marvel/>,
# <http://github.com/karmi/elasticsearch-paramedic>,
# <http://github.com/lukas-vlcek/bigdesk> and
# <http://mobz.github.com/elasticsearch-head> to inspect the cluster state.
# A node can have generic attributes associated with it, which can later be used
# for customized shard allocation filtering, or allocation awareness. An attribute
# is a simple key value pair, similar to node.key: value, here is an example:
#
#node.rack: rack314
# By default, multiple nodes are allowed to start from the same installation location
# to disable it, set the following:
#node.max_local_storage_nodes: 1
#################################### Index ####################################
# You can set a number of options (such as shard/replica options, mapping
# or analyzer definitions, translog settings, ...) for indices globally,
# in this file.
#
# Note, that it makes more sense to configure index settings specifically for
# a certain index, either when creating it or by using the index templates API.
#
# See <http://elasticsearch.org/guide/en/elasticsearch/reference/current/index-modules.html> and
# <http://elasticsearch.org/guide/en/elasticsearch/reference/current/indices-create-index.html>
# for more information.
# Set the number of shards (splits) of an index (5 by default):
#
#index.number_of_shards: 5
# Set the number of replicas (additional copies) of an index (1 by default):
#
#index.number_of_replicas: 1
# Note, that for development on a local machine, with small indices, it usually
# makes sense to "disable" the distributed features:
#
#index.number_of_shards: 1
#index.number_of_replicas: 0
# These settings directly affect the performance of index and search operations
# in your cluster. Assuming you have enough machines to hold shards and
# replicas, the rule of thumb is:
#
# 1. Having more *shards* enhances the _indexing_ performance and allows to
# _distribute_ a big index across machines.
# 2. Having more *replicas* enhances the _search_ performance and improves the
# cluster _availability_.
#
# The "number_of_shards" is a one-time setting for an index.
#
# The "number_of_replicas" can be increased or decreased anytime,
# by using the Index Update Settings API.
#
# Elasticsearch takes care about load balancing, relocating, gathering the
# results from nodes, etc. Experiment with different settings to fine-tune
# your setup.
# Use the Index Status API (<http://localhost:9200/A/_status>) to inspect
# the index status.
#################################### Paths ####################################
# Path to directory where to store index data allocated for this node.
path.data: %ES_DATA_DIR%
# Path to log files:
path.logs: %ES_LOG_DIR%
# Path to where plugins are installed:
#path.plugins: /path/to/plugins
# Path to temporary files
#path.work: /path/to/work
# Path to directory containing configuration (this file and logging.yml):
#path.conf: /path/to/conf
#################################### Plugin ###################################
# If a plugin listed here is not installed for current node, the node will not start.
#
#plugin.mandatory: mapper-attachments,lang-groovy
################################### Memory ####################################
# Elasticsearch performs poorly when JVM starts swapping: you should ensure that
# it _never_ swaps.
#
# Set this property to true to lock the memory:
#
#bootstrap.mlockall: true
# Make sure that the ES_MIN_MEM and ES_MAX_MEM environment variables are set
# to the same value, and that the machine has enough memory to allocate
# for Elasticsearch, leaving enough memory for the operating system itself.
#
# You should also make sure that the Elasticsearch process is allowed to lock
# the memory, eg. by using `ulimit -l unlimited`.
############################## Network And HTTP ###############################
# Elasticsearch, by default, binds itself to the 0.0.0.0 address, and listens
# on port [9200-9300] for HTTP traffic and on port [9300-9400] for node-to-node
# communication. (the range means that if the port is busy, it will automatically
# try the next port).
# Set the bind address specifically (IPv4 or IPv6):
network.bind_host: %ES_SERVICE_BIND_HOST%
# Set the address other nodes will use to communicate with this node. If not
# set, it is automatically derived. It must point to an actual IP address.
network.publish_host: %ES_SERVICE_PUBLISH_HOST%
# Set a custom port for the node to node communication (9300 by default):
transport.tcp.port: %ES_SERVICE_PUBLISH_PORT%
# Enable compression for all communication between nodes (disabled by default):
#
#transport.tcp.compress: true
# Set a custom port to listen for HTTP traffic:
#
http.port: %ES_SERVICE_BIND_PORT%
# Set a custom allowed content length:
#
#http.max_content_length: 100mb
# Disable HTTP completely:
#
#http.enabled: false
################################### Gateway ###################################
# The gateway allows for persisting the cluster state between full cluster
# restarts. Every change to the state (such as adding an index) will be stored
# in the gateway, and when the cluster starts up for the first time,
# it will read its state from the gateway.
# There are several types of gateway implementations. For more information, see
# <http://elasticsearch.org/guide/en/elasticsearch/reference/current/modules-gateway.html>.
# The default gateway type is the "local" gateway (recommended):
#
#gateway.type: local
# Settings below control how and when to start the initial recovery process on
# a full cluster restart (to reuse as much local data as possible when using shared
# gateway).
# Allow recovery process after N nodes in a cluster are up:
#
#gateway.recover_after_nodes: 1
# Set the timeout to initiate the recovery process, once the N nodes
# from previous setting are up (accepts time value):
#
#gateway.recover_after_time: 5m
# Set how many nodes are expected in this cluster. Once these N nodes
# are up (and recover_after_nodes is met), begin recovery process immediately
# (without waiting for recover_after_time to expire):
#
#gateway.expected_nodes: 2
############################# Recovery Throttling #############################
# These settings allow to control the process of shards allocation between
# nodes during initial recovery, replica allocation, rebalancing,
# or when adding and removing nodes.
# Set the number of concurrent recoveries happening on a node:
#
# 1. During the initial recovery
#
#cluster.routing.allocation.node_initial_primaries_recoveries: 4
#
# 2. During adding/removing nodes, rebalancing, etc
#
#cluster.routing.allocation.node_concurrent_recoveries: 2
# Set to throttle throughput when recovering (eg. 100mb, by default 20mb):
#
#indices.recovery.max_bytes_per_sec: 20mb
# Set to limit the number of open concurrent streams when
# recovering a shard from a peer:
#
#indices.recovery.concurrent_streams: 5
################################## Discovery ##################################
# Discovery infrastructure ensures nodes can be found within a cluster
# and master node is elected. Multicast discovery is the default.
# Set to ensure a node sees N other master eligible nodes to be considered
# operational within the cluster. This should be set to a quorum/majority of
# the master-eligible nodes in the cluster.
#
discovery.zen.minimum_master_nodes: 1
# Set the time to wait for ping responses from other nodes when discovering.
# Set this option to a higher value on a slow or congested network
# to minimize discovery failures:
#
#discovery.zen.ping.timeout: 3s
# For more information, see
# <http://elasticsearch.org/guide/en/elasticsearch/reference/current/modules-discovery-zen.html>
# Unicast discovery allows to explicitly control which nodes will be used
# to discover the cluster. It can be used when multicast is not present,
# or to restrict the cluster communication-wise.
#
# 1. Disable multicast discovery (enabled by default):
#
discovery.zen.ping.multicast.enabled: false
# 2. Configure an initial list of master nodes in the cluster
# to perform discovery when new nodes (master or data) are started:
#
# discovery.zen.ping.unicast.hosts: [127.0.0.1]
# EC2 discovery allows to use AWS EC2 API in order to perform discovery.
#
# You have to install the cloud-aws plugin for enabling the EC2 discovery.
#
# For more information, see
# <http://elasticsearch.org/guide/en/elasticsearch/reference/current/modules-discovery-ec2.html>
#
# See <http://elasticsearch.org/tutorials/elasticsearch-on-ec2/>
# for a step-by-step tutorial.
# GCE discovery allows to use Google Compute Engine API in order to perform discovery.
#
# You have to install the cloud-gce plugin for enabling the GCE discovery.
#
# For more information, see <https://github.com/elasticsearch/elasticsearch-cloud-gce>.
# Azure discovery allows to use Azure API in order to perform discovery.
#
# You have to install the cloud-azure plugin for enabling the Azure discovery.
#
# For more information, see <https://github.com/elasticsearch/elasticsearch-cloud-azure>.
################################## Slow Log ##################################
# Shard level query and fetch threshold logging.
#index.search.slowlog.threshold.query.warn: 10s
#index.search.slowlog.threshold.query.info: 5s
#index.search.slowlog.threshold.query.debug: 2s
#index.search.slowlog.threshold.query.trace: 500ms
#index.search.slowlog.threshold.fetch.warn: 1s
#index.search.slowlog.threshold.fetch.info: 800ms
#index.search.slowlog.threshold.fetch.debug: 500ms
#index.search.slowlog.threshold.fetch.trace: 200ms
#index.indexing.slowlog.threshold.index.warn: 10s
#index.indexing.slowlog.threshold.index.info: 5s
#index.indexing.slowlog.threshold.index.debug: 2s
#index.indexing.slowlog.threshold.index.trace: 500ms
################################## GC Logging ################################
#monitor.jvm.gc.young.warn: 1000ms
#monitor.jvm.gc.young.info: 700ms
#monitor.jvm.gc.young.debug: 400ms
#monitor.jvm.gc.old.warn: 10s
#monitor.jvm.gc.old.info: 5s
#monitor.jvm.gc.old.debug: 2s
################################## Security ################################
# Uncomment if you want to enable JSONP as a valid return transport on the
# http server. With this enabled, it may pose a security risk, so disabling
# it unless you need it is recommended (it is disabled by default).
#
#http.jsonp.enable: true

File diff suppressed because it is too large Load Diff

View File

@ -1,624 +0,0 @@
{
"id": null,
"title": "Kibana",
"tags": [
"logs"
],
"style": "dark",
"timezone": "browser",
"editable": true,
"sharedCrosshair": false,
"hideControls": false,
"time": {
"from": "now-1h",
"to": "now"
},
"timepicker": {
"refresh_intervals": [
"5s",
"10s",
"30s",
"1m",
"5m",
"15m",
"30m",
"1h",
"2h",
"1d"
],
"time_options": [
"5m",
"15m",
"1h",
"6h",
"12h",
"24h",
"2d",
"7d",
"30d"
]
},
"templating": {
"list": []
},
"annotations": {
"list": []
},
"schemaVersion": 13,
"version": 7,
"links": [],
"gnetId": null,
"rows": [
{
"title": "Dashboard Row",
"panels": [
{
"cacheTimeout": null,
"colorBackground": true,
"colorValue": false,
"colors": [
"rgba(225, 40, 40, 0.59)",
"rgba(245, 150, 40, 0.73)",
"rgba(71, 212, 59, 0.4)"
],
"format": "none",
"gauge": {
"maxValue": 100,
"minValue": 0,
"show": false,
"thresholdLabels": false,
"thresholdMarkers": true
},
"id": 1,
"interval": null,
"links": [],
"mappingType": 1,
"mappingTypes": [
],
"maxDataPoints": 100,
"nullPointMode": "connected",
"nullText": null,
"postfix": "",
"postfixFontSize": "50%",
"prefix": "",
"prefixFontSize": "50%",
"span": 4,
"sparkline": {
"fillColor": "rgba(31, 118, 189, 0.18)",
"full": false,
"lineColor": "rgb(31, 120, 193)",
"show": false
},
"targets": [
{
"aggregator": "none",
"dimensions": [
{
"key": "service",
"value": "kibana"
}
],
"error": "",
"metric": "process.pid_count",
"period": "300",
"refId": "A"
}
],
"thresholds": "0.2,0.8",
"title": "Kibana",
"type": "singlestat",
"valueFontSize": "80%",
"valueMaps": [
{
"value": "0",
"op": "=",
"text": "DOWN"
},
{
"value": "1",
"op": "=",
"text": "UP"
},
{
"value": "2",
"op": "=",
"text": "UP"
},
{
"value": "3",
"op": "=",
"text": "UP"
},
{
"value": "4",
"op": "=",
"text": "UP"
},
{
"value": "5",
"op": "=",
"text": "UP"
},
{
"value": "6",
"op": "=",
"text": "UP"
},
{
"value": "7",
"op": "=",
"text": "UP"
},
{
"value": "8",
"op": "=",
"text": "UP"
},
{
"value": "9",
"op": "=",
"text": "UP"
},
{
"value": "10",
"op": "=",
"text": "UP"
},
{
"value": "11",
"op": "=",
"text": "UP"
},
{
"value": "12",
"op": "=",
"text": "UP"
}
],
"valueName": "current"
},
{
"aliasColors": {},
"bars": false,
"datasource": null,
"fill": 1,
"id": 2,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 1,
"links": [],
"nullPointMode": "null",
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"span": 4,
"stack": false,
"steppedLine": false,
"targets": [
{
"aggregator": "avg",
"dimensions": [
{
"key": "process_name",
"value": "kibana"
}
],
"error": "",
"metric": "process.cpu_perc",
"period": "300",
"refId": "A"
}
],
"thresholds": [],
"timeFrom": null,
"timeShift": null,
"title": "CPU",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "graph",
"xaxis": {
"mode": "time",
"name": null,
"show": true,
"values": []
},
"yaxes": [
{
"format": "percent",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
]
},
{
"aliasColors": {},
"bars": false,
"datasource": null,
"fill": 1,
"id": 3,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 1,
"links": [],
"nullPointMode": "null",
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"span": 4,
"stack": false,
"steppedLine": false,
"targets": [
{
"aggregator": "avg",
"dimensions": [
{
"key": "process_name",
"value": "kibana"
}
],
"error": "",
"metric": "process.mem.rss_mbytes",
"period": "300",
"refId": "A"
}
],
"thresholds": [],
"timeFrom": null,
"timeShift": null,
"title": "Memory",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "graph",
"xaxis": {
"mode": "time",
"name": null,
"show": true,
"values": []
},
"yaxes": [
{
"format": "bytes",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
]
}
],
"showTitle": false,
"titleSize": "h6",
"height": "250px",
"repeat": null,
"repeatRowId": null,
"repeatIteration": null,
"collapse": false
},
{
"title": "Dashboard Row",
"panels": [
{
"aliasColors": {},
"bars": false,
"datasource": null,
"fill": 1,
"id": 4,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 1,
"links": [],
"nullPointMode": "null",
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"span": 6,
"stack": false,
"steppedLine": false,
"targets": [
{
"aggregator": "avg",
"dimensions": [
{
"key": "process_name",
"value": "kibana"
}
],
"error": "",
"metric": "process.io.read_count",
"period": "300",
"refId": "A"
},
{
"aggregator": "avg",
"dimensions": [
{
"key": "process_name",
"value": "kibana"
}
],
"error": "",
"metric": "process.io.write_count",
"period": "300",
"refId": "B"
}
],
"thresholds": [],
"timeFrom": null,
"timeShift": null,
"title": "IO Count",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "graph",
"xaxis": {
"mode": "time",
"name": null,
"show": true,
"values": []
},
"yaxes": [
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
]
},
{
"aliasColors": {},
"bars": false,
"datasource": null,
"fill": 1,
"id": 5,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 1,
"links": [],
"nullPointMode": "null",
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"span": 6,
"stack": false,
"steppedLine": false,
"targets": [
{
"aggregator": "avg",
"dimensions": [
{
"key": "process_name",
"value": "kibana"
}
],
"error": "",
"metric": "process.io.read_kbytes",
"period": "300",
"refId": "A"
},
{
"aggregator": "avg",
"dimensions": [
{
"key": "process_name",
"value": "kibana"
}
],
"error": "",
"metric": "process.io.write_kbytes",
"period": "300",
"refId": "B"
}
],
"thresholds": [],
"timeFrom": null,
"timeShift": null,
"title": "IO Read/Write [kB]",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "graph",
"xaxis": {
"mode": "time",
"name": null,
"show": true,
"values": []
},
"yaxes": [
{
"format": "kbytes",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
]
}
],
"showTitle": false,
"titleSize": "h6",
"height": 250,
"repeat": null,
"repeatRowId": null,
"repeatIteration": null,
"collapse": false
},
{
"title": "Dashboard Row",
"panels": [
{
"aliasColors": {},
"bars": false,
"datasource": null,
"fill": 1,
"id": 6,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 1,
"nullPointMode": "null",
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"span": 12,
"stack": false,
"steppedLine": false,
"targets": [
{
"aggregator": "avg",
"dimensions": [
{
"key": "process_name",
"value": "kibana"
}
],
"error": "",
"metric": "process.open_file_descriptors",
"period": "300",
"refId": "A"
}
],
"thresholds": [],
"timeFrom": null,
"timeShift": null,
"title": "Open File Descriptors",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "graph",
"xaxis": {
"mode": "time",
"name": null,
"show": true,
"values": []
},
"yaxes": [
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
]
}
],
"showTitle": false,
"titleSize": "h6",
"height": 250,
"repeat": null,
"repeatRowId": null,
"repeatIteration": null,
"collapse": false
}
]
}

View File

@ -1,624 +0,0 @@
{
"id": null,
"title": "Log API",
"tags": [
"logs"
],
"style": "dark",
"timezone": "browser",
"editable": true,
"sharedCrosshair": false,
"hideControls": false,
"time": {
"from": "now-1h",
"to": "now"
},
"timepicker": {
"refresh_intervals": [
"5s",
"10s",
"30s",
"1m",
"5m",
"15m",
"30m",
"1h",
"2h",
"1d"
],
"time_options": [
"5m",
"15m",
"1h",
"6h",
"12h",
"24h",
"2d",
"7d",
"30d"
]
},
"templating": {
"list": []
},
"annotations": {
"list": []
},
"schemaVersion": 13,
"version": 7,
"links": [],
"gnetId": null,
"rows": [
{
"title": "Dashboard Row",
"panels": [
{
"cacheTimeout": null,
"colorBackground": true,
"colorValue": false,
"colors": [
"rgba(225, 40, 40, 0.59)",
"rgba(245, 150, 40, 0.73)",
"rgba(71, 212, 59, 0.4)"
],
"format": "none",
"gauge": {
"maxValue": 100,
"minValue": 0,
"show": false,
"thresholdLabels": false,
"thresholdMarkers": true
},
"id": 1,
"interval": null,
"links": [],
"mappingType": 1,
"mappingTypes": [
],
"maxDataPoints": 100,
"nullPointMode": "connected",
"nullText": null,
"postfix": "",
"postfixFontSize": "50%",
"prefix": "",
"prefixFontSize": "50%",
"span": 4,
"sparkline": {
"fillColor": "rgba(31, 118, 189, 0.18)",
"full": false,
"lineColor": "rgb(31, 120, 193)",
"show": false
},
"targets": [
{
"aggregator": "none",
"dimensions": [
{
"key": "service",
"value": "log-api"
}
],
"error": "",
"metric": "process.pid_count",
"period": "300",
"refId": "A"
}
],
"thresholds": "0.2,0.8",
"title": "Log API",
"type": "singlestat",
"valueFontSize": "80%",
"valueMaps": [
{
"value": "0",
"op": "=",
"text": "DOWN"
},
{
"value": "1",
"op": "=",
"text": "UP"
},
{
"value": "2",
"op": "=",
"text": "UP"
},
{
"value": "3",
"op": "=",
"text": "UP"
},
{
"value": "4",
"op": "=",
"text": "UP"
},
{
"value": "5",
"op": "=",
"text": "UP"
},
{
"value": "6",
"op": "=",
"text": "UP"
},
{
"value": "7",
"op": "=",
"text": "UP"
},
{
"value": "8",
"op": "=",
"text": "UP"
},
{
"value": "9",
"op": "=",
"text": "UP"
},
{
"value": "10",
"op": "=",
"text": "UP"
},
{
"value": "11",
"op": "=",
"text": "UP"
},
{
"value": "12",
"op": "=",
"text": "UP"
}
],
"valueName": "current"
},
{
"aliasColors": {},
"bars": false,
"datasource": null,
"fill": 1,
"id": 2,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 1,
"links": [],
"nullPointMode": "null",
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"span": 4,
"stack": false,
"steppedLine": false,
"targets": [
{
"aggregator": "avg",
"dimensions": [
{
"key": "process_name",
"value": "log-api"
}
],
"error": "",
"metric": "process.cpu_perc",
"period": "300",
"refId": "A"
}
],
"thresholds": [],
"timeFrom": null,
"timeShift": null,
"title": "CPU",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "graph",
"xaxis": {
"mode": "time",
"name": null,
"show": true,
"values": []
},
"yaxes": [
{
"format": "percent",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
]
},
{
"aliasColors": {},
"bars": false,
"datasource": null,
"fill": 1,
"id": 3,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 1,
"links": [],
"nullPointMode": "null",
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"span": 4,
"stack": false,
"steppedLine": false,
"targets": [
{
"aggregator": "avg",
"dimensions": [
{
"key": "process_name",
"value": "log-api"
}
],
"error": "",
"metric": "process.mem.rss_mbytes",
"period": "300",
"refId": "A"
}
],
"thresholds": [],
"timeFrom": null,
"timeShift": null,
"title": "Memory",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "graph",
"xaxis": {
"mode": "time",
"name": null,
"show": true,
"values": []
},
"yaxes": [
{
"format": "bytes",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
]
}
],
"showTitle": false,
"titleSize": "h6",
"height": "250px",
"repeat": null,
"repeatRowId": null,
"repeatIteration": null,
"collapse": false
},
{
"title": "Dashboard Row",
"panels": [
{
"aliasColors": {},
"bars": false,
"datasource": null,
"fill": 1,
"id": 4,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 1,
"links": [],
"nullPointMode": "null",
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"span": 6,
"stack": false,
"steppedLine": false,
"targets": [
{
"aggregator": "avg",
"dimensions": [
{
"key": "process_name",
"value": "log-api"
}
],
"error": "",
"metric": "process.io.read_count",
"period": "300",
"refId": "A"
},
{
"aggregator": "avg",
"dimensions": [
{
"key": "process_name",
"value": "log-api"
}
],
"error": "",
"metric": "process.io.write_count",
"period": "300",
"refId": "B"
}
],
"thresholds": [],
"timeFrom": null,
"timeShift": null,
"title": "IO Count",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "graph",
"xaxis": {
"mode": "time",
"name": null,
"show": true,
"values": []
},
"yaxes": [
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
]
},
{
"aliasColors": {},
"bars": false,
"datasource": null,
"fill": 1,
"id": 5,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 1,
"links": [],
"nullPointMode": "null",
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"span": 6,
"stack": false,
"steppedLine": false,
"targets": [
{
"aggregator": "avg",
"dimensions": [
{
"key": "process_name",
"value": "log-api"
}
],
"error": "",
"metric": "process.io.read_kbytes",
"period": "300",
"refId": "A"
},
{
"aggregator": "avg",
"dimensions": [
{
"key": "process_name",
"value": "log-api"
}
],
"error": "",
"metric": "process.io.write_kbytes",
"period": "300",
"refId": "B"
}
],
"thresholds": [],
"timeFrom": null,
"timeShift": null,
"title": "IO Read/Write [kB]",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "graph",
"xaxis": {
"mode": "time",
"name": null,
"show": true,
"values": []
},
"yaxes": [
{
"format": "kbytes",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
]
}
],
"showTitle": false,
"titleSize": "h6",
"height": 250,
"repeat": null,
"repeatRowId": null,
"repeatIteration": null,
"collapse": false
},
{
"title": "Dashboard Row",
"panels": [
{
"aliasColors": {},
"bars": false,
"datasource": null,
"fill": 1,
"id": 6,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 1,
"nullPointMode": "null",
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"span": 12,
"stack": false,
"steppedLine": false,
"targets": [
{
"aggregator": "avg",
"dimensions": [
{
"key": "process_name",
"value": "log-api"
}
],
"error": "",
"metric": "process.open_file_descriptors",
"period": "300",
"refId": "A"
}
],
"thresholds": [],
"timeFrom": null,
"timeShift": null,
"title": "Open File Descriptors",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "graph",
"xaxis": {
"mode": "time",
"name": null,
"show": true,
"values": []
},
"yaxes": [
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
]
}
],
"showTitle": false,
"titleSize": "h6",
"height": 250,
"repeat": null,
"repeatRowId": null,
"repeatIteration": null,
"collapse": false
}
]
}

View File

@ -1,624 +0,0 @@
{
"id": null,
"title": "Log Transformer",
"tags": [
"logs"
],
"style": "dark",
"timezone": "browser",
"editable": true,
"sharedCrosshair": false,
"hideControls": false,
"time": {
"from": "now-1h",
"to": "now"
},
"timepicker": {
"refresh_intervals": [
"5s",
"10s",
"30s",
"1m",
"5m",
"15m",
"30m",
"1h",
"2h",
"1d"
],
"time_options": [
"5m",
"15m",
"1h",
"6h",
"12h",
"24h",
"2d",
"7d",
"30d"
]
},
"templating": {
"list": []
},
"annotations": {
"list": []
},
"schemaVersion": 13,
"version": 7,
"links": [],
"gnetId": null,
"rows": [
{
"title": "Dashboard Row",
"panels": [
{
"cacheTimeout": null,
"colorBackground": true,
"colorValue": false,
"colors": [
"rgba(225, 40, 40, 0.59)",
"rgba(245, 150, 40, 0.73)",
"rgba(71, 212, 59, 0.4)"
],
"format": "none",
"gauge": {
"maxValue": 100,
"minValue": 0,
"show": false,
"thresholdLabels": false,
"thresholdMarkers": true
},
"id": 1,
"interval": null,
"links": [],
"mappingType": 1,
"mappingTypes": [
],
"maxDataPoints": 100,
"nullPointMode": "connected",
"nullText": null,
"postfix": "",
"postfixFontSize": "50%",
"prefix": "",
"prefixFontSize": "50%",
"span": 4,
"sparkline": {
"fillColor": "rgba(31, 118, 189, 0.18)",
"full": false,
"lineColor": "rgb(31, 120, 193)",
"show": false
},
"targets": [
{
"aggregator": "none",
"dimensions": [
{
"key": "service",
"value": "log-transformer"
}
],
"error": "",
"metric": "process.pid_count",
"period": "300",
"refId": "A"
}
],
"thresholds": "0.2,0.8",
"title": "Log Transformer",
"type": "singlestat",
"valueFontSize": "80%",
"valueMaps": [
{
"value": "0",
"op": "=",
"text": "DOWN"
},
{
"value": "1",
"op": "=",
"text": "UP"
},
{
"value": "2",
"op": "=",
"text": "UP"
},
{
"value": "3",
"op": "=",
"text": "UP"
},
{
"value": "4",
"op": "=",
"text": "UP"
},
{
"value": "5",
"op": "=",
"text": "UP"
},
{
"value": "6",
"op": "=",
"text": "UP"
},
{
"value": "7",
"op": "=",
"text": "UP"
},
{
"value": "8",
"op": "=",
"text": "UP"
},
{
"value": "9",
"op": "=",
"text": "UP"
},
{
"value": "10",
"op": "=",
"text": "UP"
},
{
"value": "11",
"op": "=",
"text": "UP"
},
{
"value": "12",
"op": "=",
"text": "UP"
}
],
"valueName": "current"
},
{
"aliasColors": {},
"bars": false,
"datasource": null,
"fill": 1,
"id": 2,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 1,
"links": [],
"nullPointMode": "null",
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"span": 4,
"stack": false,
"steppedLine": false,
"targets": [
{
"aggregator": "avg",
"dimensions": [
{
"key": "process_name",
"value": "log-transformer"
}
],
"error": "",
"metric": "process.cpu_perc",
"period": "300",
"refId": "A"
}
],
"thresholds": [],
"timeFrom": null,
"timeShift": null,
"title": "CPU",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "graph",
"xaxis": {
"mode": "time",
"name": null,
"show": true,
"values": []
},
"yaxes": [
{
"format": "percent",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
]
},
{
"aliasColors": {},
"bars": false,
"datasource": null,
"fill": 1,
"id": 3,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 1,
"links": [],
"nullPointMode": "null",
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"span": 4,
"stack": false,
"steppedLine": false,
"targets": [
{
"aggregator": "avg",
"dimensions": [
{
"key": "process_name",
"value": "log-transformer"
}
],
"error": "",
"metric": "process.mem.rss_mbytes",
"period": "300",
"refId": "A"
}
],
"thresholds": [],
"timeFrom": null,
"timeShift": null,
"title": "Memory",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "graph",
"xaxis": {
"mode": "time",
"name": null,
"show": true,
"values": []
},
"yaxes": [
{
"format": "bytes",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
]
}
],
"showTitle": false,
"titleSize": "h6",
"height": "250px",
"repeat": null,
"repeatRowId": null,
"repeatIteration": null,
"collapse": false
},
{
"title": "Dashboard Row",
"panels": [
{
"aliasColors": {},
"bars": false,
"datasource": null,
"fill": 1,
"id": 4,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 1,
"links": [],
"nullPointMode": "null",
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"span": 6,
"stack": false,
"steppedLine": false,
"targets": [
{
"aggregator": "avg",
"dimensions": [
{
"key": "process_name",
"value": "log-transformer"
}
],
"error": "",
"metric": "process.io.read_count",
"period": "300",
"refId": "A"
},
{
"aggregator": "avg",
"dimensions": [
{
"key": "process_name",
"value": "log-transformer"
}
],
"error": "",
"metric": "process.io.write_count",
"period": "300",
"refId": "B"
}
],
"thresholds": [],
"timeFrom": null,
"timeShift": null,
"title": "IO Count",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "graph",
"xaxis": {
"mode": "time",
"name": null,
"show": true,
"values": []
},
"yaxes": [
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
]
},
{
"aliasColors": {},
"bars": false,
"datasource": null,
"fill": 1,
"id": 5,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 1,
"links": [],
"nullPointMode": "null",
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"span": 6,
"stack": false,
"steppedLine": false,
"targets": [
{
"aggregator": "avg",
"dimensions": [
{
"key": "process_name",
"value": "log-transformer"
}
],
"error": "",
"metric": "process.io.read_kbytes",
"period": "300",
"refId": "A"
},
{
"aggregator": "avg",
"dimensions": [
{
"key": "process_name",
"value": "log-transformer"
}
],
"error": "",
"metric": "process.io.write_kbytes",
"period": "300",
"refId": "B"
}
],
"thresholds": [],
"timeFrom": null,
"timeShift": null,
"title": "IO Read/Write [kB]",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "graph",
"xaxis": {
"mode": "time",
"name": null,
"show": true,
"values": []
},
"yaxes": [
{
"format": "kbytes",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
]
}
],
"showTitle": false,
"titleSize": "h6",
"height": 250,
"repeat": null,
"repeatRowId": null,
"repeatIteration": null,
"collapse": false
},
{
"title": "Dashboard Row",
"panels": [
{
"aliasColors": {},
"bars": false,
"datasource": null,
"fill": 1,
"id": 6,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 1,
"nullPointMode": "null",
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"span": 12,
"stack": false,
"steppedLine": false,
"targets": [
{
"aggregator": "avg",
"dimensions": [
{
"key": "process_name",
"value": "log-transformer"
}
],
"error": "",
"metric": "process.open_file_descriptors",
"period": "300",
"refId": "A"
}
],
"thresholds": [],
"timeFrom": null,
"timeShift": null,
"title": "Open File Descriptors",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "graph",
"xaxis": {
"mode": "time",
"name": null,
"show": true,
"values": []
},
"yaxes": [
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
]
}
],
"showTitle": false,
"titleSize": "h6",
"height": 250,
"repeat": null,
"repeatRowId": null,
"repeatIteration": null,
"collapse": false
}
]
}

View File

@ -1,624 +0,0 @@
{
"id": null,
"title": "Log Metrics",
"tags": [
"logs"
],
"style": "dark",
"timezone": "browser",
"editable": true,
"sharedCrosshair": false,
"hideControls": false,
"time": {
"from": "now-1h",
"to": "now"
},
"timepicker": {
"refresh_intervals": [
"5s",
"10s",
"30s",
"1m",
"5m",
"15m",
"30m",
"1h",
"2h",
"1d"
],
"time_options": [
"5m",
"15m",
"1h",
"6h",
"12h",
"24h",
"2d",
"7d",
"30d"
]
},
"templating": {
"list": []
},
"annotations": {
"list": []
},
"schemaVersion": 13,
"version": 7,
"links": [],
"gnetId": null,
"rows": [
{
"title": "Dashboard Row",
"panels": [
{
"cacheTimeout": null,
"colorBackground": true,
"colorValue": false,
"colors": [
"rgba(225, 40, 40, 0.59)",
"rgba(245, 150, 40, 0.73)",
"rgba(71, 212, 59, 0.4)"
],
"format": "none",
"gauge": {
"maxValue": 100,
"minValue": 0,
"show": false,
"thresholdLabels": false,
"thresholdMarkers": true
},
"id": 1,
"interval": null,
"links": [],
"mappingType": 1,
"mappingTypes": [
],
"maxDataPoints": 100,
"nullPointMode": "connected",
"nullText": null,
"postfix": "",
"postfixFontSize": "50%",
"prefix": "",
"prefixFontSize": "50%",
"span": 4,
"sparkline": {
"fillColor": "rgba(31, 118, 189, 0.18)",
"full": false,
"lineColor": "rgb(31, 120, 193)",
"show": false
},
"targets": [
{
"aggregator": "none",
"dimensions": [
{
"key": "service",
"value": "log-metrics"
}
],
"error": "",
"metric": "process.pid_count",
"period": "300",
"refId": "A"
}
],
"thresholds": "0.2,0.8",
"title": "Log Metrics",
"type": "singlestat",
"valueFontSize": "80%",
"valueMaps": [
{
"value": "0",
"op": "=",
"text": "DOWN"
},
{
"value": "1",
"op": "=",
"text": "UP"
},
{
"value": "2",
"op": "=",
"text": "UP"
},
{
"value": "3",
"op": "=",
"text": "UP"
},
{
"value": "4",
"op": "=",
"text": "UP"
},
{
"value": "5",
"op": "=",
"text": "UP"
},
{
"value": "6",
"op": "=",
"text": "UP"
},
{
"value": "7",
"op": "=",
"text": "UP"
},
{
"value": "8",
"op": "=",
"text": "UP"
},
{
"value": "9",
"op": "=",
"text": "UP"
},
{
"value": "10",
"op": "=",
"text": "UP"
},
{
"value": "11",
"op": "=",
"text": "UP"
},
{
"value": "12",
"op": "=",
"text": "UP"
}
],
"valueName": "current"
},
{
"aliasColors": {},
"bars": false,
"datasource": null,
"fill": 1,
"id": 2,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 1,
"links": [],
"nullPointMode": "null",
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"span": 4,
"stack": false,
"steppedLine": false,
"targets": [
{
"aggregator": "avg",
"dimensions": [
{
"key": "process_name",
"value": "log-metrics"
}
],
"error": "",
"metric": "process.cpu_perc",
"period": "300",
"refId": "A"
}
],
"thresholds": [],
"timeFrom": null,
"timeShift": null,
"title": "CPU",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "graph",
"xaxis": {
"mode": "time",
"name": null,
"show": true,
"values": []
},
"yaxes": [
{
"format": "percent",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
]
},
{
"aliasColors": {},
"bars": false,
"datasource": null,
"fill": 1,
"id": 3,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 1,
"links": [],
"nullPointMode": "null",
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"span": 4,
"stack": false,
"steppedLine": false,
"targets": [
{
"aggregator": "avg",
"dimensions": [
{
"key": "process_name",
"value": "log-metrics"
}
],
"error": "",
"metric": "process.mem.rss_mbytes",
"period": "300",
"refId": "A"
}
],
"thresholds": [],
"timeFrom": null,
"timeShift": null,
"title": "Memory",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "graph",
"xaxis": {
"mode": "time",
"name": null,
"show": true,
"values": []
},
"yaxes": [
{
"format": "bytes",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
]
}
],
"showTitle": false,
"titleSize": "h6",
"height": "250px",
"repeat": null,
"repeatRowId": null,
"repeatIteration": null,
"collapse": false
},
{
"title": "Dashboard Row",
"panels": [
{
"aliasColors": {},
"bars": false,
"datasource": null,
"fill": 1,
"id": 4,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 1,
"links": [],
"nullPointMode": "null",
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"span": 6,
"stack": false,
"steppedLine": false,
"targets": [
{
"aggregator": "avg",
"dimensions": [
{
"key": "process_name",
"value": "log-metrics"
}
],
"error": "",
"metric": "process.io.read_count",
"period": "300",
"refId": "A"
},
{
"aggregator": "avg",
"dimensions": [
{
"key": "process_name",
"value": "log-metrics"
}
],
"error": "",
"metric": "process.io.write_count",
"period": "300",
"refId": "B"
}
],
"thresholds": [],
"timeFrom": null,
"timeShift": null,
"title": "IO Count",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "graph",
"xaxis": {
"mode": "time",
"name": null,
"show": true,
"values": []
},
"yaxes": [
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
]
},
{
"aliasColors": {},
"bars": false,
"datasource": null,
"fill": 1,
"id": 5,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 1,
"links": [],
"nullPointMode": "null",
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"span": 6,
"stack": false,
"steppedLine": false,
"targets": [
{
"aggregator": "avg",
"dimensions": [
{
"key": "process_name",
"value": "log-metrics"
}
],
"error": "",
"metric": "process.io.read_kbytes",
"period": "300",
"refId": "A"
},
{
"aggregator": "avg",
"dimensions": [
{
"key": "process_name",
"value": "log-metrics"
}
],
"error": "",
"metric": "process.io.write_kbytes",
"period": "300",
"refId": "B"
}
],
"thresholds": [],
"timeFrom": null,
"timeShift": null,
"title": "IO Read/Write [kB]",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "graph",
"xaxis": {
"mode": "time",
"name": null,
"show": true,
"values": []
},
"yaxes": [
{
"format": "kbytes",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
]
}
],
"showTitle": false,
"titleSize": "h6",
"height": 250,
"repeat": null,
"repeatRowId": null,
"repeatIteration": null,
"collapse": false
},
{
"title": "Dashboard Row",
"panels": [
{
"aliasColors": {},
"bars": false,
"datasource": null,
"fill": 1,
"id": 6,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 1,
"nullPointMode": "null",
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"span": 12,
"stack": false,
"steppedLine": false,
"targets": [
{
"aggregator": "avg",
"dimensions": [
{
"key": "process_name",
"value": "log-metrics"
}
],
"error": "",
"metric": "process.open_file_descriptors",
"period": "300",
"refId": "A"
}
],
"thresholds": [],
"timeFrom": null,
"timeShift": null,
"title": "Open File Descriptors",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "graph",
"xaxis": {
"mode": "time",
"name": null,
"show": true,
"values": []
},
"yaxes": [
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
]
}
],
"showTitle": false,
"titleSize": "h6",
"height": 250,
"repeat": null,
"repeatRowId": null,
"repeatIteration": null,
"collapse": false
}
]
}

View File

@ -1,624 +0,0 @@
{
"id": null,
"title": "Log Persister",
"tags": [
"logs"
],
"style": "dark",
"timezone": "browser",
"editable": true,
"sharedCrosshair": false,
"hideControls": false,
"time": {
"from": "now-1h",
"to": "now"
},
"timepicker": {
"refresh_intervals": [
"5s",
"10s",
"30s",
"1m",
"5m",
"15m",
"30m",
"1h",
"2h",
"1d"
],
"time_options": [
"5m",
"15m",
"1h",
"6h",
"12h",
"24h",
"2d",
"7d",
"30d"
]
},
"templating": {
"list": []
},
"annotations": {
"list": []
},
"schemaVersion": 13,
"version": 7,
"links": [],
"gnetId": null,
"rows": [
{
"title": "Dashboard Row",
"panels": [
{
"cacheTimeout": null,
"colorBackground": true,
"colorValue": false,
"colors": [
"rgba(225, 40, 40, 0.59)",
"rgba(245, 150, 40, 0.73)",
"rgba(71, 212, 59, 0.4)"
],
"format": "none",
"gauge": {
"maxValue": 100,
"minValue": 0,
"show": false,
"thresholdLabels": false,
"thresholdMarkers": true
},
"id": 1,
"interval": null,
"links": [],
"mappingType": 1,
"mappingTypes": [
],
"maxDataPoints": 100,
"nullPointMode": "connected",
"nullText": null,
"postfix": "",
"postfixFontSize": "50%",
"prefix": "",
"prefixFontSize": "50%",
"span": 4,
"sparkline": {
"fillColor": "rgba(31, 118, 189, 0.18)",
"full": false,
"lineColor": "rgb(31, 120, 193)",
"show": false
},
"targets": [
{
"aggregator": "none",
"dimensions": [
{
"key": "service",
"value": "log-persister"
}
],
"error": "",
"metric": "process.pid_count",
"period": "300",
"refId": "A"
}
],
"thresholds": "0.2,0.8",
"title": "Log Persister",
"type": "singlestat",
"valueFontSize": "80%",
"valueMaps": [
{
"value": "0",
"op": "=",
"text": "DOWN"
},
{
"value": "1",
"op": "=",
"text": "UP"
},
{
"value": "2",
"op": "=",
"text": "UP"
},
{
"value": "3",
"op": "=",
"text": "UP"
},
{
"value": "4",
"op": "=",
"text": "UP"
},
{
"value": "5",
"op": "=",
"text": "UP"
},
{
"value": "6",
"op": "=",
"text": "UP"
},
{
"value": "7",
"op": "=",
"text": "UP"
},
{
"value": "8",
"op": "=",
"text": "UP"
},
{
"value": "9",
"op": "=",
"text": "UP"
},
{
"value": "10",
"op": "=",
"text": "UP"
},
{
"value": "11",
"op": "=",
"text": "UP"
},
{
"value": "12",
"op": "=",
"text": "UP"
}
],
"valueName": "current"
},
{
"aliasColors": {},
"bars": false,
"datasource": null,
"fill": 1,
"id": 2,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 1,
"links": [],
"nullPointMode": "null",
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"span": 4,
"stack": false,
"steppedLine": false,
"targets": [
{
"aggregator": "avg",
"dimensions": [
{
"key": "process_name",
"value": "log-persister"
}
],
"error": "",
"metric": "process.cpu_perc",
"period": "300",
"refId": "A"
}
],
"thresholds": [],
"timeFrom": null,
"timeShift": null,
"title": "CPU",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "graph",
"xaxis": {
"mode": "time",
"name": null,
"show": true,
"values": []
},
"yaxes": [
{
"format": "percent",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
]
},
{
"aliasColors": {},
"bars": false,
"datasource": null,
"fill": 1,
"id": 3,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 1,
"links": [],
"nullPointMode": "null",
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"span": 4,
"stack": false,
"steppedLine": false,
"targets": [
{
"aggregator": "avg",
"dimensions": [
{
"key": "process_name",
"value": "log-persister"
}
],
"error": "",
"metric": "process.mem.rss_mbytes",
"period": "300",
"refId": "A"
}
],
"thresholds": [],
"timeFrom": null,
"timeShift": null,
"title": "Memory",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "graph",
"xaxis": {
"mode": "time",
"name": null,
"show": true,
"values": []
},
"yaxes": [
{
"format": "bytes",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
]
}
],
"showTitle": false,
"titleSize": "h6",
"height": "250px",
"repeat": null,
"repeatRowId": null,
"repeatIteration": null,
"collapse": false
},
{
"title": "Dashboard Row",
"panels": [
{
"aliasColors": {},
"bars": false,
"datasource": null,
"fill": 1,
"id": 4,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 1,
"links": [],
"nullPointMode": "null",
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"span": 6,
"stack": false,
"steppedLine": false,
"targets": [
{
"aggregator": "avg",
"dimensions": [
{
"key": "process_name",
"value": "log-persister"
}
],
"error": "",
"metric": "process.io.read_count",
"period": "300",
"refId": "A"
},
{
"aggregator": "avg",
"dimensions": [
{
"key": "process_name",
"value": "log-persister"
}
],
"error": "",
"metric": "process.io.write_count",
"period": "300",
"refId": "B"
}
],
"thresholds": [],
"timeFrom": null,
"timeShift": null,
"title": "IO Count",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "graph",
"xaxis": {
"mode": "time",
"name": null,
"show": true,
"values": []
},
"yaxes": [
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
]
},
{
"aliasColors": {},
"bars": false,
"datasource": null,
"fill": 1,
"id": 5,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 1,
"links": [],
"nullPointMode": "null",
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"span": 6,
"stack": false,
"steppedLine": false,
"targets": [
{
"aggregator": "avg",
"dimensions": [
{
"key": "process_name",
"value": "log-persister"
}
],
"error": "",
"metric": "process.io.read_kbytes",
"period": "300",
"refId": "A"
},
{
"aggregator": "avg",
"dimensions": [
{
"key": "process_name",
"value": "log-persister"
}
],
"error": "",
"metric": "process.io.write_kbytes",
"period": "300",
"refId": "B"
}
],
"thresholds": [],
"timeFrom": null,
"timeShift": null,
"title": "IO Read/Write [kB]",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "graph",
"xaxis": {
"mode": "time",
"name": null,
"show": true,
"values": []
},
"yaxes": [
{
"format": "kbytes",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
]
}
],
"showTitle": false,
"titleSize": "h6",
"height": 250,
"repeat": null,
"repeatRowId": null,
"repeatIteration": null,
"collapse": false
},
{
"title": "Dashboard Row",
"panels": [
{
"aliasColors": {},
"bars": false,
"datasource": null,
"fill": 1,
"id": 6,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 1,
"nullPointMode": "null",
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"span": 12,
"stack": false,
"steppedLine": false,
"targets": [
{
"aggregator": "avg",
"dimensions": [
{
"key": "process_name",
"value": "log-persister"
}
],
"error": "",
"metric": "process.open_file_descriptors",
"period": "300",
"refId": "A"
}
],
"thresholds": [],
"timeFrom": null,
"timeShift": null,
"title": "Open File Descriptors",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "graph",
"xaxis": {
"mode": "time",
"name": null,
"show": true,
"values": []
},
"yaxes": [
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
]
}
],
"showTitle": false,
"titleSize": "h6",
"height": 250,
"repeat": null,
"repeatRowId": null,
"repeatIteration": null,
"collapse": false
}
]
}

View File

@ -1,115 +0,0 @@
#!/usr/bin/env python
# coding=utf-8
# (C) Copyright 2017 Hewlett Packard Enterprise Development LP
# (C) Copyright 2018 FUJITSU LIMITED
#
# 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 glob
import json
import logging
import os
import sys
import time
from requests import RequestException
from requests import Session
LOG_LEVEL = logging.getLevelName(os.environ.get('LOG_LEVEL', 'INFO'))
logging.basicConfig(level=LOG_LEVEL)
logger = logging.getLogger(__name__)
GRAFANA_URL = os.environ.get('GRAFANA_URL', 'http://localhost:3000')
GRAFANA_USERNAME = os.environ.get('GRAFANA_USERNAME', 'mini-mon')
GRAFANA_PASSWORD = os.environ.get('GRAFANA_PASSWORD', 'password')
GRAFANA_USERS = [{'user': GRAFANA_USERNAME, 'password': GRAFANA_PASSWORD, 'email': ''}]
DASHBOARDS_DIR = sys.argv[1]
def retry(retries=5, delay=2.0, exc_types=(RequestException,)):
def decorator(func):
def f_retry(*args, **kwargs):
for i in range(retries):
try:
return func(*args, **kwargs)
except exc_types as exc:
if i < retries - 1:
logger.debug('Caught exception, retrying...',
exc_info=True)
time.sleep(delay)
else:
logger.exception('Failed after %d attempts', retries)
if isinstance(exc, RequestException):
logger.debug('Response was: %r', exc.response.text)
raise
return f_retry
return decorator
def create_login_payload():
if os.environ.get('GRAFANA_USERS'):
try:
json.loads(os.environ.get('GRAFANA_USERS'))
except ValueError:
print("Invalid type GRAFANA_USERS")
raise
grafana_users = json.loads(os.environ.get('GRAFANA_USERS'))
else:
grafana_users = GRAFANA_USERS
return grafana_users
@retry(retries=24, delay=5.0)
def login(session, user):
r = session.post('{url}/login'.format(url=GRAFANA_URL),
json=user,
timeout=5)
r.raise_for_status()
def create_dashboard_payload(json_path):
with open(json_path, 'r') as f:
dashboard = json.load(f)
dashboard['id'] = None
return {
'dashboard': dashboard,
'overwrite': True
}
def main():
for user in create_login_payload():
logging.info('Opening a Grafana session...')
session = Session()
login(session, user)
for path in sorted(glob.glob('{dir}/*.json'.format(dir=DASHBOARDS_DIR))):
logging.info('Creating dashboard from file: {path}'.format(path=path))
r = session.post('{url}/api/dashboards/db'.format(url=GRAFANA_URL),
json=create_dashboard_payload(path))
logging.debug('Response: %r', r.json())
r.raise_for_status()
logging.info('Ending %r session...', user.get('user'))
session.get('{url}/logout'.format(url=GRAFANA_URL))
logging.info('Finished successfully.')
if __name__ == '__main__':
main()

View File

@ -1,78 +0,0 @@
# Kibana is served by a back end server. This controls which port to use.
server.port: %KIBANA_SERVICE_PORT%
# The host to bind the server to.
server.host: %KIBANA_SERVICE_HOST%
# If you are running kibana behind a proxy, and want to mount it at a path,
# specify that path here. The basePath can't end in a slash.
server.basePath: /dashboard/monitoring/logs_proxy
# The Elasticsearch instance to use for all your queries.
elasticsearch.url: http://%ES_SERVICE_BIND_HOST%:%ES_SERVICE_BIND_PORT%
# preserve_elasticsearch_host true will send the hostname specified in `elasticsearch`. If you set it to false,
# then the host you use to connect to *this* Kibana instance will be sent.
elasticsearch.preserveHost: True
# Kibana uses an index in Elasticsearch to store saved searches, visualizations
# and dashboards. It will create a new index if it doesn't already exist.
kibana.index: ".kibana"
# The default application to load.
kibana.defaultAppId: "discover"
# If your Elasticsearch is protected with basic auth, these are the user credentials
# used by the Kibana server to perform maintenance on the kibana_index at startup. Your Kibana
# users will still need to authenticate with Elasticsearch (which is proxied through
# the Kibana server)
# elasticsearch.username: "user"
# elasticsearch.password: "pass"
# SSL for outgoing requests from the Kibana Server to the browser (PEM formatted)
# server.ssl.cert: /path/to/your/server.crt
# server.ssl.key: /path/to/your/server.key
# Optional setting to validate that your Elasticsearch backend uses the same key files (PEM formatted)
# elasticsearch.ssl.cert: /path/to/your/client.crt
# elasticsearch.ssl.key: /path/to/your/client.key
# If you need to provide a CA certificate for your Elasticsearch instance, put
# the path of the pem file here.
# elasticsearch.ssl.ca: /path/to/your/CA.pem
# Set to false to have a complete disregard for the validity of the SSL
# certificate.
# elasticsearch.ssl.verify: true
# Time in milliseconds to wait for elasticsearch to respond to pings, defaults to
# request_timeout setting
elasticsearch.pingTimeout: 1500
# Time in milliseconds to wait for responses from the back end or elasticsearch.
# This must be > 0
elasticsearch.requestTimeout: 300000
# Time in milliseconds for Elasticsearch to wait for responses from shards.
# Set to 0 to disable.
elasticsearch.shardTimeout: 0
# Time in milliseconds to wait for Elasticsearch at Kibana startup before retrying
elasticsearch.startupTimeout: 5000
# Set the path to where you would like the process id file to be created.
# pid.file: /var/run/kibana.pid
# Set this to true to suppress all logging output.
logging.silent: false
# Set this to true to suppress all logging output except for error messages.
logging.quiet: false
# Set this to true to log all events, including system usage information and all requests.
logging.verbose: true
# monasca-kibana-plugin configuration
monasca-kibana-plugin.auth_uri: %KEYSTONE_AUTH_URI%
monasca-kibana-plugin.enabled: True
monasca-kibana-plugin.cookie.isSecure: False
optimize.useBundleCache: False

View File

@ -1,3 +0,0 @@
init_config:
instances:
- url: http://{{IP}}:9200

View File

@ -1,27 +0,0 @@
init_config: null
instances:
- name: keystone
dimensions:
service: keystone
timeout: 3
url: http://127.0.0.1/identity
- name: mysql
dimensions:
service: mysql
timeout: 3
url: http://127.0.0.1:3306
- name: influxdb
dimensions:
service: influxdb
timeout: 3
url: http://127.0.0.1:8086/ping
- name: elasticsearch
dimensions:
service: elasticsearch
timeout: 3
url: http://{{IP}}:9200/_cat/health
- name: kibana
dimensions:
service: kibana
timeout: 3
url: http://{{IP}}:5601/status

View File

@ -1,143 +0,0 @@
init_config:
instances:
- name: influxd
detailed: true
dimensions:
service: influxd
exact_match: false
search_string:
- influxd
- name: monasca-statsd
detailed: true
dimensions:
service: monasca-statsd
exact_match: false
search_string:
- monasca-statsd
- name: monasca-notification
detailed: true
dimensions:
service: monasca-notification
exact_match: false
search_string:
- monasca-notification
- name: persister
detailed: true
dimensions:
service: persister
exact_match: false
search_string:
- persister
- name: storm
detailed: true
dimensions:
service: storm
exact_match: false
search_string:
- storm
- name: monasca-api
detailed: true
dimensions:
service: uwsgi
exact_match: false
search_string:
- uwsgi
- name: monasca-collector
detailed: true
dimensions:
service: monasca-collector
exact_match: false
search_string:
- monasca-collector
- name: memcached
detailed: true
dimensions:
service: memcached
exact_match: false
search_string:
- memcached
- name: monasca-forwarder
detailed: true
dimensions:
service: monasca-forwarder
exact_match: false
search_string:
- monasca-forwarder
- name: zookeeper
detailed: true
dimensions:
service: zookeeper
exact_match: false
search_string:
- zookeeper
- name: kafka
detailed: true
dimensions:
service: kafka
exact_match: false
search_string:
- kafka
- name: mysqld
detailed: true
dimensions:
service: mysqld
exact_match: false
search_string:
- mysqld
- name: logspout
detailed: true
dimensions:
service: logspout
exact_match: false
search_string:
- logspout
- name: log-agent
detailed: true
dimensions:
service: log-agent
exact_match: false
search_string:
- log-agent
- name: log-api
detailed: true
dimensions:
service: log-api
exact_match: false
search_string:
- log-api
- name: kibana
detailed: true
dimensions:
service: kibana
exact_match: false
search_string:
- kibana
- name: elasticsearch
detailed: true
dimensions:
service: elasticsearch
exact_match: false
search_string:
- elasticsearch
- name: log-transformer
detailed: true
dimensions:
service: log-transformer
exact_match: false
search_string:
- log-transformer
- name: log-persister
detailed: true
dimensions:
service: log-persister
exact_match: false
search_string:
- log-persister
- name: log-metrics
detailed: true
dimensions:
service: log-metrics
exact_match: false
search_string:
- log-metrics

View File

@ -1,47 +0,0 @@
#
# Copyright 2016 FUJITSU LIMITED
#
# 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.
#
input {
file {
add_field => { "dimensions" => { "service" => "system" }}
path => "/var/log/syslog"
tags => ["syslog"]
}
}
filter {
if "syslog" in [tags] {
multiline {
negate => "true"
pattern => "^%{SYSLOGTIMESTAMP}"
what => "previous"
}
}
}
# TODO(trebskit) should use own user for log-agent
output {
monasca_log_api {
monasca_log_api_url => "%MONASCA_LOG_API_URI_V3%"
keystone_api_url => "%KEYSTONE_AUTH_URI_V3%"
project_name => "mini-mon"
username => "monasca-agent"
password => "password"
user_domain_name => "default"
project_domain_name => "default"
dimensions => [ "hostname:devstack" ]
}
}

View File

@ -1,81 +0,0 @@
# Copyright 2016 FUJITSU LIMITED
#
# 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.
input {
kafka {
zk_connect => "127.0.0.1:2181"
topic_id => "transformed-log"
group_id => "log-metric"
consumer_id => "monasca_log_metrics"
consumer_threads => "4"
}
}
filter {
# drop logs that have not set log level
if "level" not in [log] {
drop { periodic_flush => true }
} else {
ruby {
code => "
log_level = event['log']['level'].downcase
event['log']['level'] = log_level
"
}
}
# drop logs with log level not in warning,error
if [log][level] not in [warning,error] {
drop { periodic_flush => true }
}
ruby {
code => "
log_level = event['log']['level'].downcase
log_ts = Time.now.to_f * 1000.0
# metric name
metric_name = 'log.%s' % log_level
# build metric
metric = {}
metric['name'] = metric_name
metric['timestamp'] = log_ts
metric['value'] = 1
metric['dimensions'] = event['log']['dimensions']
metric['value_meta'] = {}
event['metric'] = metric.to_hash
"
}
mutate {
remove_field => ["log", "@version", "@timestamp", "log_level_original", "tags"]
}
}
output {
kafka {
bootstrap_servers => "%KAFKA_SERVICE_HOST%:%KAFKA_SERVICE_PORT%"
topic_id => "metrics"
client_id => "monasca_log_metrics"
compression_type => "none"
}
}

View File

@ -1,71 +0,0 @@
#
# Copyright 2016 FUJITSU LIMITED
#
# 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.
#
input {
kafka {
zk_connect => "127.0.0.1:2181"
topic_id => "transformed-log"
group_id => "logstash-persister"
}
}
filter {
date {
match => ["[log][timestamp]", "UNIX"]
target => "@timestamp"
}
date {
match => ["creation_time", "UNIX"]
target => "creation_time"
}
grok {
match => {
"[@timestamp]" => "^(?<index_date>\d{4}-\d{2}-\d{2})"
}
}
if "dimensions" in [log] {
ruby {
code => "
fieldHash = event['log']['dimensions']
fieldHash.each do |key, value|
event[key] = value
end
"
}
}
mutate {
add_field => {
message => "%{[log][message]}"
log_level => "%{[log][level]}"
tenant => "%{[meta][tenantId]}"
region => "%{[meta][region]}"
}
remove_field => ["@version", "host", "type", "tags" ,"_index_date", "meta", "log"]
}
}
output {
elasticsearch {
index => "logs-%{tenant}-%{index_date}"
document_type => "log"
hosts => ["%ES_SERVICE_BIND_HOST%"]
flush_size => 500
}
}

View File

@ -1,87 +0,0 @@
#
# Copyright 2016 FUJITSU LIMITED
#
# 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.
#
input {
kafka {
zk_connect => "127.0.0.1:2181"
topic_id => "log"
group_id => "transformer-logstash-consumer"
}
}
filter {
ruby {
code => "event['message_tmp'] = event['log']['message'][0..49]"
}
grok {
match => {
"[message_tmp]" => "(?i)(?<log_level>AUDIT|CRITICAL|DEBUG|INFO|TRACE|ERR(OR)?|WARN(ING)?)|\"level\":\s?(?<log_level>\d{2})"
}
}
if ! [log_level] {
grok {
match => {
"[log][message]" => "(?i)(?<log_level>AUDIT|CRITICAL|DEBUG|INFO|TRACE|ERR(OR)?|WARN(ING)?)|\"level\":\s?(?<log_level>\d{2})"
}
}
}
ruby {
init => "
LOG_LEVELS_MAP = {
# SYSLOG
'warn' => :Warning,
'err' => :Error,
# Bunyan errcodes
'10' => :Trace,
'20' => :Debug,
'30' => :Info,
'40' => :Warning,
'50' => :Error,
'60' => :Fatal
}
"
code => "
if event['log_level']
# keep original value
log_level = event['log_level'].downcase
if LOG_LEVELS_MAP.has_key?(log_level)
event['log_level_original'] = event['log_level']
event['log_level'] = LOG_LEVELS_MAP[log_level]
else
event['log_level'] = log_level.capitalize
end
else
event['log_level'] = 'Unknown'
end
"
}
mutate {
add_field => {
"[log][level]" => "%{log_level}"
}
# remove temporary fields
remove_field => ["log_level", "message_tmp"]
}
}
output {
kafka {
bootstrap_servers => "%KAFKA_SERVICE_HOST%:%KAFKA_SERVICE_PORT%"
topic_id => "transformed-log"
}
}

View File

@ -1,107 +0,0 @@
#!/bin/bash
# Copyright 2017 FUJITSU LIMITED
#
# 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.
# Non configurable settings or settings derived from another settings
_XTRACE_LOG_API_CONFIG=$(set +o | grep xtrace)
set +o xtrace
if [[ ${USE_VENV} = True ]]; then
PROJECT_VENV["monasca-log-api"]=${MONASCA_LOG_API_DIR}.venv
MONASCA_LOG_API_BIN_DIR=${PROJECT_VENV["monasca-log-api"]}/bin
else
MONASCA_LOG_API_BIN_DIR=$(get_python_exec_prefix)
fi
MONASCA_LOG_API_WSGI=$MONASCA_LOG_API_BIN_DIR/monasca-log-api-wsgi
MONASCA_LOG_API_DEPLOY=`determine_log_api_deploy_mode`
if is_service_enabled tls-proxy; then
MONASCA_LOG_API_SERVICE_PROTOCOL="https"
fi
if [ "$MONASCA_LOG_API_USE_MOD_WSGI" == "True" ]; then
MONASCA_LOG_API_BASE_URI=${MONASCA_LOG_API_SERVICE_PROTOCOL}://${MONASCA_LOG_API_SERVICE_HOST}/logs
else
MONASCA_LOG_API_BASE_URI=${MONASCA_LOG_API_SERVICE_PROTOCOL}://${MONASCA_LOG_API_SERVICE_HOST}:${MONASCA_LOG_API_SERVICE_PORT}
fi
MONASCA_LOG_API_URI_V2=${MONASCA_LOG_API_BASE_URI}/v2.0
MONASCA_LOG_API_URI_V3=${MONASCA_LOG_API_BASE_URI}/v3.0
MONASCA_LOG_API_CONF_DIR=${MONASCA_LOG_API_CONF_DIR:-/etc/monasca}
MONASCA_LOG_API_LOG_DIR=${MONASCA_LOG_API_LOG_DIR:-/var/log/monasca}
MONASCA_LOG_API_CACHE_DIR=${MONASCA_LOG_API_CACHE_DIR:-/var/cache/monasca-log-api}
MONASCA_LOG_API_WSGI_DIR=${MONASCA_LOG_API_WSGI_DIR:-/var/www/monasca-log-api}
MONASCA_LOG_API_CONF=${MONASCA_LOG_API_CONF:-$MONASCA_LOG_API_CONF_DIR/monasca-log-api.conf}
MONASCA_LOG_API_PASTE=${MONASCA_LOG_API_PASTE:-$MONASCA_LOG_API_CONF_DIR/log-api-paste.ini}
MONASCA_LOG_API_LOGGING_CONF=${MONASCA_LOG_API_LOGGING_CONF:-$MONASCA_LOG_API_CONF_DIR/log-api-logging.conf}
MONASCA_LOG_API_UWSGI_CONF=${MONASCA_LOG_API_UWSGI_CONF:-$MONASCA_LOG_API_CONF_DIR/log-api-uwsgi.ini}
MONASCA_LOG_API_USE_MOD_WSGI=${MONASCA_LOG_API_USE_MOD_WSGI:-$ENABLE_HTTPD_MOD_WSGI_SERVICES}
# configuration bits of various services
LOG_PERSISTER_DIR=$DEST/monasca-log-persister
LOG_TRANSFORMER_DIR=$DEST/monasca-log-transformer
LOG_METRICS_DIR=$DEST/monasca-log-metrics
LOG_AGENT_DIR=$DEST/monasca-log-agent
ELASTICSEARCH_DIR=$DEST/elasticsearch
ELASTICSEARCH_CFG_DIR=$ELASTICSEARCH_DIR/config
ELASTICSEARCH_LOG_DIR=$LOGDIR/elasticsearch
ELASTICSEARCH_DATA_DIR=$DATA_DIR/elasticsearch
KIBANA_DIR=$DEST/kibana
KIBANA_CFG_DIR=$KIBANA_DIR/config
LOGSTASH_DIR=$DEST/logstash
PLUGIN_FILES=$MONASCA_LOG_API_DIR/devstack/files
# configuration bits of various services
# Files inside this directory will be visible in gates log
GATE_CONFIGURATION_DIR=/etc/monasca-log-api
# clone monasca-{common,statsd} directly from repo
GITREPO["monasca-common"]=${MONASCA_COMMON_REPO}
GITBRANCH["monasca-common"]=${MONASCA_COMMON_BRANCH}
GITDIR["monasca-common"]=${MONASCA_COMMON_DIR}
GITREPO["monasca-statsd"]=${MONASCA_STATSD_REPO}
GITBRANCH["monasca-statsd"]=${MONASCA_STATSD_BRANCH}
GITDIR["monasca-statsd"]=${MONASCA_STATSD_DIR}
LIBS_FROM_GIT="${LIBS_FROM_GIT:-""},monasca-common,monasca-statsd"
# clone monasca-{common,statsd} directly from repo
# public facing bits
MONASCA_LOG_API_SERVICE_HOST=${MONASCA_LOG_API_SERVICE_HOST:-${SERVICE_HOST}}
MONASCA_LOG_API_SERVICE_PORT=${MONASCA_LOG_API_SERVICE_PORT:-5607}
MONASCA_LOG_API_SERVICE_PORT_INT=${MONASCA_LOG_API_SERVICE_PORT:-15607}
MONASCA_LOG_API_SERVICE_PROTOCOL=${MONASCA_LOG_API_SERVICE_PROTOCOL:-${SERVICE_PROTOCOL}}
ES_SERVICE_BIND_HOST=${ES_SERVICE_BIND_HOST:-${SERVICE_HOST}}
ES_SERVICE_BIND_PORT=${ES_SERVICE_BIND_PORT:-9200}
ES_SERVICE_PUBLISH_HOST=${ES_SERVICE_PUBLISH_HOST:-${SERVICE_HOST}}
ES_SERVICE_PUBLISH_PORT=${ES_SERVICE_PUBLISH_PORT:-9300}
KIBANA_SERVICE_HOST=${KIBANA_SERVICE_HOST:-${SERVICE_HOST}}
KIBANA_SERVICE_PORT=${KIBANA_SERVICE_PORT:-5601}
KIBANA_SERVER_BASE_PATH=${KIBANA_SERVER_BASE_PATH:-"/dashboard/monitoring/logs_proxy"}
KAFKA_SERVICE_HOST=${KAFKA_SERVICE_HOST:-${SERVICE_HOST}}
KAFKA_SERVICE_PORT=${KAFKA_SERVICE_PORT:-9092}
# public facing bits
${_XTRACE_LOG_API_CONFIG}

View File

@ -1,56 +0,0 @@
#!/bin/bash
# Copyright 2017 FUJITSU LIMITED
#
# 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.
# Set of utility-like methods that are not bound to any particular
# service
_XTRACE_LOG_API_UTILS=$(set +o | grep xtrace)
set +o xtrace
run_process_sleep() {
local name=$1
local cmd=$2
local sleepTime=${3:-1}
run_process "$name" "$cmd"
sleep ${sleepTime}
}
is_logstash_required() {
is_service_enabled monasca-log-persister \
|| is_service_enabled monasca-log-transformer \
|| is_service_enabled monasca-log-metrics \
|| is_service_enabled monasca-log-agent \
&& return 0
}
# MONASCA_LOG_API_DEPLOY defines how monasca-log-api is deployed, allowed values:
# - mod_wsgi : Run monasca-log-api under Apache HTTPd mod_wsgi
# - uwsgi : Run monasca-log-api under uwsgi
# - gunicorn: Run monasca-log-api under gunicorn
determine_log_api_deploy_mode() {
MONASCA_LOG_API_USE_MOD_WSGI=$(trueorfalse False MONASCA_LOG_API_USE_MOD_WSGI)
if [ "$MONASCA_LOG_API_USE_MOD_WSGI" == "True" ]; then
if [[ "$WSGI_MODE" == "uwsgi" ]]; then
echo "uwsgi"
else
echo "mod_wsgi"
fi
else
echo "gunicorn"
fi
}
${_XTRACE_LOG_API_UTILS}

View File

@ -1,862 +0,0 @@
#!/bin/bash
#
# Copyright 2016-2017 FUJITSU LIMITED
#
# 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.
#
# Save trace setting
_XTRACE_LOG_API=$(set +o | grep xtrace)
set -o xtrace
_ERREXIT_LOG_API=$(set +o | grep errexit)
set -o errexit
# source lib/*
source ${MONASCA_LOG_API_DIR}/devstack/lib/util.sh
source ${MONASCA_LOG_API_DIR}/devstack/lib/config.sh
# source lib/*
# TOP_LEVEL functions called from devstack coordinator
###############################################################################
function pre_install {
install_elk
install_nodejs
install_gate_config_holder
}
function install_monasca_log {
build_kibana_plugin
if is_service_enabled monasca-log-api; then
# install_monasca-log-api is not called directly
# stack_install_service calls it
if python3_enabled; then
enable_python3_package monasca-log-api
fi
stack_install_service monasca-log-api
fi
install_log_agent
}
function install_elk {
install_logstash
install_elasticsearch
install_kibana
}
function install_gate_config_holder {
sudo install -d -o $STACK_USER $GATE_CONFIGURATION_DIR
}
function install_monasca_common {
if use_library_from_git "monasca-common"; then
git_clone_by_name "monasca-common"
setup_dev_lib "monasca-common"
fi
}
function install_monasca_statsd {
if use_library_from_git "monasca-statsd"; then
git_clone_by_name "monasca-statsd"
setup_dev_lib "monasca-statsd"
fi
}
function configure_monasca_log {
configure_kafka
configure_elasticsearch
configure_kibana
install_kibana_plugin
configure_monasca_log_api
configure_monasca_log_transformer
configure_monasca_log_metrics
configure_monasca_log_persister
configure_monasca_log_agent
}
function init_monasca_log {
enable_log_management
create_log_management_accounts
}
function init_monasca_grafana_dashboards {
if is_service_enabled horizon; then
echo_summary "Init Grafana dashboards"
sudo python3 "${PLUGIN_FILES}"/grafana/grafana.py "${PLUGIN_FILES}"/grafana/dashboards.d
fi
}
function init_agent {
echo_summary "Init Monasca agent"
sudo cp -f "${PLUGIN_FILES}"/monasca-agent/http_check.yaml /etc/monasca/agent/conf.d/http_check.yaml
sudo cp -f "${PLUGIN_FILES}"/monasca-agent/process.yaml /etc/monasca/agent/conf.d/process.yaml
sudo cp -f "${PLUGIN_FILES}"/monasca-agent/elastic.yaml /etc/monasca/agent/conf.d/elastic.yaml
sudo sed -i "s/{{IP}}/$(ip -o -4 addr list eth1 | awk '{print $4}' | cut -d/ -f1 | head -1)/" /etc/monasca/agent/conf.d/*.yaml
sudo sed -i "s/127\.0\.0\.1/$(hostname)/" /etc/monasca/agent/conf.d/*.yaml
sudo systemctl restart monasca-collector
}
function stop_monasca_log {
stop_process "monasca-log-agent" || true
stop_monasca_log_api
stop_process "monasca-log-metrics" || true
stop_process "monasca-log-persister" || true
stop_process "monasca-log-transformer" || true
stop_process "kibana" || true
stop_process "elasticsearch" || true
}
function start_monasca_log {
start_elasticsearch
start_kibana
start_monasca_log_transformer
start_monasca_log_metrics
start_monasca_log_persister
start_monasca_log_api
start_monasca_log_agent
}
function clean_monasca_log {
clean_monasca_log_agent
clean_monasca_log_api
clean_monasca_log_persister
clean_monasca_log_transformer
clean_kibana
clean_elasticsearch
clean_logstash
clean_nodejs
clean_gate_config_holder
}
###############################################################################
function install_monasca-log-api {
echo_summary "Installing monasca-log-api"
git_clone $MONASCA_LOG_API_REPO $MONASCA_LOG_API_DIR $MONASCA_LOG_API_BRANCH
setup_develop $MONASCA_LOG_API_DIR
install_keystonemiddleware
install_monasca_common
install_monasca_statsd
if [ "$MONASCA_LOG_API_DEPLOY" == "mod_wsgi" ]; then
install_apache_wsgi
elif [ "$MONASCA_LOG_API_DEPLOY" == "uwsgi" ]; then
pip_install uwsgi
else
pip_install gunicorn
fi
if [ "$MONASCA_LOG_API_DEPLOY" != "gunicorn" ]; then
if is_ssl_enabled_service "monasca-log-api"; then
enable_mod_ssl
fi
fi
}
function configure_monasca_log_api {
if is_service_enabled monasca-log-api; then
echo_summary "Configuring monasca-log-api"
configure_monasca_log_api_core
if [ "$MONASCA_LOG_API_DEPLOY" == "mod_wsgi" ]; then
configure_monasca_log_api_mod_wsgi
elif [ "$MONASCA_LOG_API_DEPLOY" == "uwsgi" ]; then
configure_monasca_log_api_uwsgi
fi
# link configuration for the gate
ln -sf $MONASCA_LOG_API_CONF $GATE_CONFIGURATION_DIR
ln -sf $MONASCA_LOG_API_PASTE $GATE_CONFIGURATION_DIR
ln -sf $MONASCA_LOG_API_LOGGING_CONF $GATE_CONFIGURATION_DIR
fi
}
function configure_monasca_log_api_core {
# Put config files in ``$MONASCA_LOG_API_CONF_DIR`` for everyone to find
sudo install -d -o $STACK_USER $MONASCA_LOG_API_CONF_DIR
sudo install -m 700 -d -o $STACK_USER $MONASCA_LOG_API_CACHE_DIR
sudo install -d -o $STACK_USER $MONASCA_LOG_API_LOG_DIR
# ensure fresh installation of configuration files
rm -rf $MONASCA_LOG_API_CONF $MONASCA_LOG_API_PASTE $MONASCA_LOG_API_LOGGING_CONF
$MONASCA_LOG_API_BIN_DIR/oslo-config-generator \
--config-file $MONASCA_LOG_API_DIR/config-generator/monasca-log-api.conf \
--output-file /tmp/monasca-log-api.conf
install -m 600 /tmp/monasca-log-api.conf $MONASCA_LOG_API_CONF && rm -rf /tmp/monasca-log-api.conf
install -m 600 $MONASCA_LOG_API_DIR/etc/monasca/log-api-paste.ini $MONASCA_LOG_API_PASTE
install -m 600 $MONASCA_LOG_API_DIR/etc/monasca/log-api-logging.conf $MONASCA_LOG_API_LOGGING_CONF
# configure monasca-log-api.conf
iniset "$MONASCA_LOG_API_CONF" DEFAULT log_config_append $MONASCA_LOG_API_LOGGING_CONF
iniset "$MONASCA_LOG_API_CONF" service region $REGION_NAME
iniset "$MONASCA_LOG_API_CONF" log_publisher kafka_url $KAFKA_SERVICE_HOST:$KAFKA_SERVICE_PORT
iniset "$MONASCA_LOG_API_CONF" log_publisher topics log
iniset "$MONASCA_LOG_API_CONF" kafka_healthcheck kafka_url $KAFKA_SERVICE_HOST:$KAFKA_SERVICE_PORT
iniset "$MONASCA_LOG_API_CONF" kafka_healthcheck kafka_topics log
iniset "$MONASCA_LOG_API_CONF" roles_middleware path "/v2.0/log,/v3.0/logs"
iniset "$MONASCA_LOG_API_CONF" roles_middleware default_roles monasca-user
iniset "$MONASCA_LOG_API_CONF" roles_middleware agent_roles monasca-agent
iniset "$MONASCA_LOG_API_CONF" roles_middleware delegate_roles admin
# configure keystone middleware
configure_auth_token_middleware "$MONASCA_LOG_API_CONF" "admin" $MONASCA_LOG_API_CACHE_DIR
iniset "$MONASCA_LOG_API_CONF" keystone_authtoken region_name $REGION_NAME
iniset "$MONASCA_LOG_API_CONF" keystone_authtoken project_name "admin"
iniset "$MONASCA_LOG_API_CONF" keystone_authtoken password $ADMIN_PASSWORD
# insecure
if is_service_enabled tls-proxy; then
iniset "$MONASCA_LOG_API_CONF" keystone_authtoken insecure False
fi
# configure log-api-paste.ini
iniset "$MONASCA_LOG_API_PASTE" server:main bind $MONASCA_LOG_API_SERVICE_HOST:$MONASCA_LOG_API_SERVICE_PORT
iniset "$MONASCA_LOG_API_PASTE" server:main chdir $MONASCA_LOG_API_DIR
iniset "$MONASCA_LOG_API_PASTE" server:main workers $API_WORKERS
}
function configure_monasca_log_api_uwsgi {
rm -rf $MONASCA_LOG_API_UWSGI_CONF
install -m 600 $MONASCA_LOG_API_DIR/etc/monasca/log-api-uwsgi.ini $MONASCA_LOG_API_UWSGI_CONF
write_uwsgi_config "$MONASCA_LOG_API_UWSGI_CONF" "$MONASCA_LOG_API_WSGI" "/logs"
}
function configure_monasca_log_api_mod_wsgi {
sudo install -d $MONASCA_LOG_API_WSGI_DIR
local monasca_log_api_apache_conf
monasca_log_api_apache_conf=$(apache_site_config_for monasca-log-api)
local monasca_log_api_ssl=""
local monasca_log_api_certfile=""
local monasca_log_api_keyfile=""
local monasca_log_api_api_port=$MONASCA_LOG_API_SERVICE_PORT
local venv_path=""
if is_ssl_enabled_service monasca_log_api; then
monasca_log_api_ssl="SSLEngine On"
monasca_log_api_certfile="SSLCertificateFile $MONASCA_LOG_API_SSL_CERT"
monasca_log_api_keyfile="SSLCertificateKeyFile $MONASCA_LOG_API_SSL_KEY"
fi
if is_service_enabled tls-proxy; then
monasca_log_api_api_port=$MONASCA_LOG_API_SERVICE_PORT_INT
fi
if [[ ${USE_VENV} = True ]]; then
venv_path="python-path=${PROJECT_VENV["monasca_log_api"]}/lib/$(python_version)/site-packages"
fi
# copy proxy vhost and wsgi helper files
sudo cp $PLUGIN_FILES/apache-log-api.template $monasca_log_api_apache_conf
sudo sed -e "
s|%PUBLICPORT%|$monasca_log_api_api_port|g;
s|%APACHE_NAME%|$APACHE_NAME|g;
s|%PUBLICWSGI%|$MONASCA_LOG_API_BIN_DIR/monasca-log-api-wsgi|g;
s|%SSLENGINE%|$monasca_log_api_ssl|g;
s|%SSLCERTFILE%|$monasca_log_api_certfile|g;
s|%SSLKEYFILE%|$monasca_log_api_keyfile|g;
s|%USER%|$STACK_USER|g;
s|%VIRTUALENV%|$venv_path|g
s|%APIWORKERS%|$API_WORKERS|g
" -i $monasca_log_api_apache_conf
}
function create_log_api_cache_dir {
sudo install -m 700 -d -o $STACK_USER $MONASCA_LOG_API_CACHE_DIR
}
function clean_monasca_log_api {
if is_service_enabled monasca-log-api; then
echo_summary "Cleaning monasca-log-api"
sudo rm -f $MONASCA_LOG_API_CONF || true
sudo rm -f $MONASCA_LOG_API_PASTE || true
sudo rm -f $MONASCA_LOG_API_LOGGING_CONF || true
sudo rm -rf $MONASCA_LOG_API_CACHE_DIR || true
sudo rm -rf $MONASCA_LOG_API_CONF_DIR || true
sudo rm -rf $MONASCA_LOG_API_DIR || true
if [ "$MONASCA_LOG_API_USE_MOD_WSGI" == "True" ]; then
clean_monasca_log_api_wsgi
fi
fi
}
function clean_monasca_log_api_wsgi {
sudo rm -f $MONASCA_LOG_API_WSGI_DIR/*
sudo rm -f $(apache_site_config_for monasca-log-api)
}
function start_monasca_log_api {
if is_service_enabled monasca-log-api; then
echo_summary "Starting monasca-log-api"
local service_port=$MONASCA_LOG_API_SERVICE_PORT
local service_protocol=$MONASCA_LOG_API_SERVICE_PROTOCOL
if is_service_enabled tls-proxy; then
service_port=$MONASCA_LOG_API_SERVICE_PORT_INT
service_protocol="http"
fi
local service_uri
if [ "$MONASCA_LOG_API_DEPLOY" == "mod_wsgi" ]; then
local enabled_site_file
enabled_site_file=$(apache_site_config_for monasca-log-api)
service_uri=$service_protocol://$MONASCA_LOG_API_SERVICE_HOST/logs/v3.0
if [ -f ${enabled_site_file} ]; then
enable_apache_site monasca-log-api
restart_apache_server
tail_log monasca-log-api /var/log/$APACHE_NAME/monasca-log-api.log
fi
elif [ "$MONASCA_LOG_API_DEPLOY" == "uwsgi" ]; then
service_uri=$service_protocol://$MONASCA_LOG_API_SERVICE_HOST/logs/v3.0
run_process "monasca-log-api" "$MONASCA_LOG_API_BIN_DIR/uwsgi --ini $MONASCA_LOG_API_UWSGI_CONF" ""
else
service_uri=$service_protocol://$MONASCA_LOG_API_SERVICE_HOST:$service_port
run_process "monasca-log-api" "$MONASCA_LOG_API_BIN_DIR/gunicorn --paste $MONASCA_LOG_API_PASTE" ""
fi
echo "Waiting for monasca-log-api to start..."
if ! wait_for_service $SERVICE_TIMEOUT $service_uri; then
die $LINENO "monasca-log-api did not start"
fi
if is_service_enabled tls-proxy; then
start_tls_proxy monasca-log-api '*' $MONASCA_LOG_API_SERVICE_PORT $MONASCA_LOG_API_SERVICE_HOST $MONASCA_LOG_API_SERVICE_PORT_INT
fi
restart_service memcached
fi
}
function stop_monasca_log_api {
if is_service_enabled monasca-log-api; then
if [ "$MONASCA_LOG_API_DEPLOY" == "mod_wsgi" ]; then
disable_apache_site monasca-log-api
restart_apache_server
else
stop_process "monasca-log-api"
if [ "$MONASCA_LOG_API_DEPLOY" == "uwsgi" ]; then
remove_uwsgi_config "$MONASCA_LOG_API_UWSGI_CONF" "$MONASCA_LOG_API_WSGI"
fi
fi
fi
}
function install_logstash {
if is_logstash_required; then
echo_summary "Installing Logstash ${LOGSTASH_VERSION}"
local logstash_tarball=logstash-${LOGSTASH_VERSION}.tar.gz
local logstash_url=http://download.elastic.co/logstash/logstash/${logstash_tarball}
local logstash_dest
logstash_dest=`get_extra_file ${logstash_url}`
tar xzf ${logstash_dest} -C $DEST
sudo chown -R $STACK_USER $DEST/logstash-${LOGSTASH_VERSION}
ln -sf $DEST/logstash-${LOGSTASH_VERSION} $LOGSTASH_DIR
fi
}
function clean_logstash {
if is_logstash_required; then
echo_summary "Cleaning Logstash ${LOGSTASH_VERSION}"
sudo rm -rf $LOGSTASH_DIR || true
sudo rm -rf $FILES/logstash-${LOGSTASH_VERSION}.tar.gz || true
sudo rm -rf $DEST/logstash-${LOGSTASH_VERSION} || true
fi
}
function install_elasticsearch {
if is_service_enabled elasticsearch; then
echo_summary "Installing ElasticSearch ${ELASTICSEARCH_VERSION}"
local es_tarball=elasticsearch-${ELASTICSEARCH_VERSION}.tar.gz
local es_url=https://download.elastic.co/elasticsearch/release/org/elasticsearch/distribution/tar/elasticsearch/${ELASTICSEARCH_VERSION}/${es_tarball}
local es_dest
es_dest=`get_extra_file ${es_url}`
tar xzf ${es_dest} -C $DEST
sudo chown -R $STACK_USER $DEST/elasticsearch-${ELASTICSEARCH_VERSION}
ln -sf $DEST/elasticsearch-${ELASTICSEARCH_VERSION} $ELASTICSEARCH_DIR
fi
}
function configure_elasticsearch {
if is_service_enabled elasticsearch; then
echo_summary "Configuring ElasticSearch ${ELASTICSEARCH_VERSION}"
local templateDir=$ELASTICSEARCH_CFG_DIR/templates
for dir in $ELASTICSEARCH_LOG_DIR $templateDir $ELASTICSEARCH_DATA_DIR; do
sudo install -m 755 -d -o $STACK_USER $dir
done
sudo cp -f "${PLUGIN_FILES}"/elasticsearch/elasticsearch.yml $ELASTICSEARCH_CFG_DIR/elasticsearch.yml
sudo chown -R $STACK_USER $ELASTICSEARCH_CFG_DIR/elasticsearch.yml
sudo chmod 0644 $ELASTICSEARCH_CFG_DIR/elasticsearch.yml
sudo sed -e "
s|%ES_SERVICE_BIND_HOST%|$ES_SERVICE_BIND_HOST|g;
s|%ES_SERVICE_BIND_PORT%|$ES_SERVICE_BIND_PORT|g;
s|%ES_SERVICE_PUBLISH_HOST%|$ES_SERVICE_PUBLISH_HOST|g;
s|%ES_SERVICE_PUBLISH_PORT%|$ES_SERVICE_PUBLISH_PORT|g;
s|%ES_DATA_DIR%|$ELASTICSEARCH_DATA_DIR|g;
s|%ES_LOG_DIR%|$ELASTICSEARCH_LOG_DIR|g;
" -i $ELASTICSEARCH_CFG_DIR/elasticsearch.yml
ln -sf $ELASTICSEARCH_CFG_DIR/elasticsearch.yml $GATE_CONFIGURATION_DIR/elasticsearch.yml
fi
}
function clean_elasticsearch {
if is_service_enabled elasticsearch; then
echo_summary "Cleaning Elasticsearch ${ELASTICSEARCH_VERSION}"
sudo rm -rf ELASTICSEARCH_DIR || true
sudo rm -rf ELASTICSEARCH_CFG_DIR || true
sudo rm -rf ELASTICSEARCH_LOG_DIR || true
sudo rm -rf ELASTICSEARCH_DATA_DIR || true
sudo rm -rf $FILES/elasticsearch-${ELASTICSEARCH_VERSION}.tar.gz || true
sudo rm -rf $DEST/elasticsearch-${ELASTICSEARCH_VERSION} || true
fi
}
function start_elasticsearch {
if is_service_enabled elasticsearch; then
echo_summary "Starting ElasticSearch ${ELASTICSEARCH_VERSION}"
# 5 extra seconds to ensure that ES started properly
local esSleepTime=${ELASTICSEARCH_SLEEP_TIME:-5}
run_process_sleep "elasticsearch" "$ELASTICSEARCH_DIR/bin/elasticsearch" $esSleepTime
fi
}
function _get_kibana_version_name {
echo "kibana-${KIBANA_VERSION}-linux-x86_64"
}
function install_kibana {
if is_service_enabled kibana; then
echo_summary "Installing Kibana ${KIBANA_VERSION}"
local kibana_version_name
kibana_version_name=`_get_kibana_version_name`
local kibana_tarball=${kibana_version_name}.tar.gz
local kibana_tarball_url=http://download.elastic.co/kibana/kibana/${kibana_tarball}
local kibana_tarball_dest
kibana_tarball_dest=`get_extra_file ${kibana_tarball_url}`
tar xzf ${kibana_tarball_dest} -C $DEST
sudo chown -R $STACK_USER $DEST/${kibana_version_name}
ln -sf $DEST/${kibana_version_name} $KIBANA_DIR
fi
}
function configure_kibana {
if is_service_enabled kibana; then
echo_summary "Configuring Kibana ${KIBANA_VERSION}"
sudo install -m 755 -d -o $STACK_USER $KIBANA_CFG_DIR
sudo cp -f "${PLUGIN_FILES}"/kibana/kibana.yml $KIBANA_CFG_DIR/kibana.yml
sudo chown -R $STACK_USER $KIBANA_CFG_DIR/kibana.yml
sudo chmod 0644 $KIBANA_CFG_DIR/kibana.yml
sudo sed -e "
s|%KIBANA_SERVICE_HOST%|$KIBANA_SERVICE_HOST|g;
s|%KIBANA_SERVICE_PORT%|$KIBANA_SERVICE_PORT|g;
s|%KIBANA_SERVER_BASE_PATH%|$KIBANA_SERVER_BASE_PATH|g;
s|%ES_SERVICE_BIND_HOST%|$ES_SERVICE_BIND_HOST|g;
s|%ES_SERVICE_BIND_PORT%|$ES_SERVICE_BIND_PORT|g;
s|%KEYSTONE_AUTH_URI%|$KEYSTONE_AUTH_URI|g;
" -i $KIBANA_CFG_DIR/kibana.yml
ln -sf $KIBANA_CFG_DIR/kibana.yml $GATE_CONFIGURATION_DIR/kibana.yml
fi
}
function install_kibana_plugin {
if is_service_enabled kibana; then
echo_summary "Install Kibana plugin"
# note(trebskit) that needs to happen after kibana received
# its configuration otherwise the plugin fails to be installed
local pkg=file://$DEST/monasca-kibana-plugin.tar.gz
$KIBANA_DIR/bin/kibana plugin -r monasca-kibana-plugin
$KIBANA_DIR/bin/kibana plugin -i monasca-kibana-plugin -u $pkg
fi
}
function clean_kibana {
if is_service_enabled kibana; then
echo_summary "Cleaning Kibana ${KIBANA_VERSION}"
local kibana_tarball
kibana_tarball=`_get_kibana_version_name`.tar.gz
sudo rm -rf $KIBANA_DIR || true
sudo rm -rf $FILES/${kibana_tarball} || true
sudo rm -rf $KIBANA_CFG_DIR || true
fi
}
function start_kibana {
if is_service_enabled kibana; then
echo_summary "Starting Kibana ${KIBANA_VERSION}"
local kibanaSleepTime=${KIBANA_SLEEP_TIME:-90} # kibana takes some time to load up
local kibanaCFG="$KIBANA_CFG_DIR/kibana.yml"
run_process_sleep "kibana" "$KIBANA_DIR/bin/kibana --config $kibanaCFG" $kibanaSleepTime
fi
}
function configure_monasca_log_persister {
if is_service_enabled monasca-log-persister; then
echo_summary "Configuring monasca-log-persister"
sudo install -m 755 -d -o $STACK_USER $LOG_PERSISTER_DIR
sudo cp -f "${PLUGIN_FILES}"/monasca-log-persister/persister.conf $LOG_PERSISTER_DIR/persister.conf
sudo chown $STACK_USER $LOG_PERSISTER_DIR/persister.conf
sudo chmod 0640 $LOG_PERSISTER_DIR/persister.conf
sudo sed -e "
s|%ES_SERVICE_BIND_HOST%|$ES_SERVICE_BIND_HOST|g;
" -i $LOG_PERSISTER_DIR/persister.conf
ln -sf $LOG_PERSISTER_DIR/persister.conf $GATE_CONFIGURATION_DIR/log-persister.conf
fi
}
function clean_monasca_log_persister {
if is_service_enabled monasca-log-persister; then
echo_summary "Cleaning monasca-log-persister"
sudo rm -rf $LOG_PERSISTER_DIR || true
fi
}
function start_monasca_log_persister {
if is_service_enabled monasca-log-persister; then
echo_summary "Starting monasca-log-persister"
local logstash="$LOGSTASH_DIR/bin/logstash"
run_process "monasca-log-persister" "$logstash -f $LOG_PERSISTER_DIR/persister.conf"
fi
}
function configure_monasca_log_transformer {
if is_service_enabled monasca-log-transformer; then
echo_summary "Configuring monasca-log-transformer"
sudo install -m 755 -d -o $STACK_USER $LOG_TRANSFORMER_DIR
sudo cp -f "${PLUGIN_FILES}"/monasca-log-transformer/transformer.conf $LOG_TRANSFORMER_DIR/transformer.conf
sudo chown $STACK_USER $LOG_TRANSFORMER_DIR/transformer.conf
sudo chmod 0640 $LOG_TRANSFORMER_DIR/transformer.conf
sudo sed -e "
s|%KAFKA_SERVICE_HOST%|$KAFKA_SERVICE_HOST|g;
s|%KAFKA_SERVICE_PORT%|$KAFKA_SERVICE_PORT|g;
" -i $LOG_TRANSFORMER_DIR/transformer.conf
ln -sf $LOG_TRANSFORMER_DIR/transformer.conf $GATE_CONFIGURATION_DIR/log-transformer.conf
fi
}
function clean_monasca_log_transformer {
if is_service_enabled monasca-log-transformer; then
echo_summary "Cleaning monasca-log-transformer"
sudo rm -rf $LOG_TRANSFORMER_DIR || true
fi
}
function start_monasca_log_transformer {
if is_service_enabled monasca-log-transformer; then
echo_summary "Starting monasca-log-transformer"
local logstash="$LOGSTASH_DIR/bin/logstash"
run_process "monasca-log-transformer" "$logstash -f $LOG_TRANSFORMER_DIR/transformer.conf"
fi
}
function configure_monasca_log_metrics {
if is_service_enabled monasca-log-metrics; then
echo_summary "Configuring monasca-log-metrics"
sudo install -m 755 -d -o $STACK_USER $LOG_METRICS_DIR
sudo cp -f "${PLUGIN_FILES}"/monasca-log-metrics/log-metrics.conf $LOG_METRICS_DIR/log-metrics.conf
sudo chown $STACK_USER $LOG_METRICS_DIR/log-metrics.conf
sudo chmod 0640 $LOG_METRICS_DIR/log-metrics.conf
sudo sed -e "
s|%KAFKA_SERVICE_HOST%|$KAFKA_SERVICE_HOST|g;
s|%KAFKA_SERVICE_PORT%|$KAFKA_SERVICE_PORT|g;
" -i $LOG_METRICS_DIR/log-metrics.conf
ln -sf $LOG_METRICS_DIR/log-metrics.conf $GATE_CONFIGURATION_DIR/log-metrics.conf
fi
}
function clean_monasca_log_metrics {
if is_service_enabled monasca-log-metrics; then
echo_summary "Cleaning monasca-log-metrics"
sudo rm -rf $LOG_METRICS_DIR || true
fi
}
function start_monasca_log_metrics {
if is_service_enabled monasca-log-metrics; then
echo_summary "Starting monasca-log-metrics"
local logstash="$LOGSTASH_DIR/bin/logstash"
run_process "monasca-log-metrics" "$logstash -f $LOG_METRICS_DIR/log-metrics.conf"
fi
}
function install_log_agent {
if is_service_enabled monasca-log-agent; then
echo_summary "Installing monasca-log-agent [monasca-output-plugin]"
$LOGSTASH_DIR/bin/plugin install --version \
"${LOGSTASH_OUTPUT_MONASCA_VERSION}" logstash-output-monasca_log_api
fi
}
function configure_monasca_log_agent {
if is_service_enabled monasca-log-agent; then
echo_summary "Configuring monasca-log-agent"
sudo install -m 755 -d -o $STACK_USER $LOG_AGENT_DIR
sudo cp -f "${PLUGIN_FILES}"/monasca-log-agent/agent.conf $LOG_AGENT_DIR/agent.conf
sudo chown $STACK_USER $LOG_AGENT_DIR/agent.conf
sudo chmod 0640 $LOG_AGENT_DIR/agent.conf
sudo sed -e "
s|%MONASCA_LOG_API_URI_V3%|$MONASCA_LOG_API_URI_V3|g;
s|%KEYSTONE_AUTH_URI_V3%|$KEYSTONE_AUTH_URI_V3|g;
" -i $LOG_AGENT_DIR/agent.conf
ln -sf $LOG_AGENT_DIR/agent.conf $GATE_CONFIGURATION_DIR/log-agent.conf
fi
}
function clean_monasca_log_agent {
if is_service_enabled monasca-log-agent; then
echo_summary "Cleaning monasca-log-agent"
sudo rm -rf $LOG_AGENT_DIR || true
fi
}
function start_monasca_log_agent {
if is_service_enabled monasca-log-agent; then
echo_summary "Starting monasca-log-agent"
local logstash="$LOGSTASH_DIR/bin/logstash"
run_process "monasca-log-agent" "$logstash -f $LOG_AGENT_DIR/agent.conf" "root" "root"
fi
}
function install_nodejs {
if is_service_enabled kibana; then
# refresh installation
curl -sL https://deb.nodesource.com/setup_10.x | sudo bash -
apt_get install nodejs
(
npm config set registry "http://registry.npmjs.org/"; \
npm config set proxy "${HTTP_PROXY}"; \
npm set strict-ssl false;
)
fi
}
function clean_nodejs {
if is_service_enabled kibana; then
echo_summary "Cleaning Node.js"
apt_get purge nodejs
fi
}
function clean_gate_config_holder {
sudo rm -rf $GATE_CONFIGURATION_DIR || true
}
function build_kibana_plugin {
if is_service_enabled kibana; then
echo "Building Kibana plugin"
git_clone $MONASCA_KIBANA_PLUGIN_REPO \
$MONASCA_KIBANA_PLUGIN_DIR \
$MONASCA_KIBANA_PLUGIN_BRANCH
pushd $MONASCA_KIBANA_PLUGIN_DIR
git_update_branch $MONASCA_KIBANA_PLUGIN_BRANCH
local monasca_kibana_plugin_version
monasca_kibana_plugin_version="$(python -c 'import json; \
obj = json.load(open("package.json")); print obj["version"]')"
npm install
npm run package
local pkg=$MONASCA_KIBANA_PLUGIN_DIR/target/monasca-kibana-plugin-${monasca_kibana_plugin_version}.tar.gz
local easyPkg=$DEST/monasca-kibana-plugin.tar.gz
ln -sf $pkg $easyPkg
popd
fi
}
function configure_kafka {
echo_summary "Configuring Kafka topics"
/opt/kafka/bin/kafka-topics.sh --create --zookeeper localhost:2181 \
--replication-factor 1 --partitions 4 --topic log
/opt/kafka/bin/kafka-topics.sh --create --zookeeper localhost:2181 \
--replication-factor 1 --partitions 4 --topic transformed-log
}
function delete_kafka_topics {
echo_summary "Deleting Kafka topics"
/opt/kafka/bin/kafka-topics.sh --delete --zookeeper localhost:2181 \
--topic log || true
/opt/kafka/bin/kafka-topics.sh --delete --zookeeper localhost:2181 \
--topic transformed-log || true
}
function create_log_management_accounts {
if is_service_enabled monasca-log-api; then
echo_summary "Enable Log Management in Keystone"
# note(trebskit) following points to Kibana which is bad,
# but we do not have search-api in monasca-log-api now
# this code will be removed in future
local log_search_url="http://$KIBANA_SERVICE_HOST:$KIBANA_SERVICE_PORT/"
get_or_create_service "logs" "logs" "Monasca Log service"
get_or_create_endpoint \
"logs" \
"$REGION_NAME" \
"$MONASCA_LOG_API_URI_V3" \
"$MONASCA_LOG_API_URI_V3" \
"$MONASCA_LOG_API_URI_V3"
get_or_create_service "logs-search" "logs-search" "Monasca Log search service"
get_or_create_endpoint \
"logs-search" \
"$REGION_NAME" \
"$log_search_url" \
"$log_search_url" \
"$log_search_url"
fi
}
function enable_log_management {
if is_service_enabled horizon && is_service_enabled kibana; then
echo_summary "Configure Horizon with Kibana access"
local localSettings=${DEST}/horizon/monitoring/config/local_settings.py
sudo sed -e "
s|KIBANA_HOST = getattr(settings, 'KIBANA_HOST', 'http://192.168.10.4:5601/')|KIBANA_HOST = getattr(settings, 'KIBANA_HOST', 'http://${KIBANA_SERVICE_HOST}:${KIBANA_SERVICE_PORT}/')|g;
" -i ${localSettings}
if is_service_enabled monasca-log-api; then
sudo sed -e "
s|'ENABLE_LOG_MANAGEMENT_BUTTON', False|'ENABLE_LOG_MANAGEMENT_BUTTON', True|g;
" -i ${localSettings}
fi
restart_apache_server
fi
}
function configure_tempest_for_monasca {
iniset $TEMPEST_CONFIG monitoring kibana_version $KIBANA_VERSION
}
# check for service enabled
if is_service_enabled monasca-log; then
if [[ "$1" == "stack" && "$2" == "pre-install" ]]; then
# Set up system services
echo_summary "Configuring Monasca Log Management system services"
pre_install
elif [[ "$1" == "stack" && "$2" == "install" ]]; then
# Perform installation of service source
echo_summary "Installing Monasca Log Management"
install_monasca_log
elif [[ "$1" == "stack" && "$2" == "test-config" ]]; then
if is_service_enabled tempest; then
echo_summary "Configuring Tempest for Monasca"
configure_tempest_for_monasca
fi
elif [[ "$1" == "stack" && "$2" == "post-config" ]]; then
# Configure after the other layer 1 and 2 services have been configured
echo_summary "Configuring Monasca Log Management"
configure_monasca_log
elif [[ "$1" == "stack" && "$2" == "extra" ]]; then
# Initialize and start the Monasca service
echo_summary "Initializing Monasca Log Management"
init_monasca_log
init_monasca_grafana_dashboards
if is_service_enabled monasca-agent; then
init_agent
fi
start_monasca_log
fi
if [[ "$1" == "unstack" ]]; then
# Shut down Monasca services
echo_summary "Unstacking Monasca Log Management"
stop_monasca_log
delete_kafka_topics
fi
if [[ "$1" == "clean" ]]; then
# Remove state and transient data
# Remember clean.sh first calls unstack.sh
echo_summary "Cleaning Monasca Log Management"
clean_monasca_log
fi
fi
#Restore errexit
$_ERREXIT_LOG_API
# Restore xtrace
$_XTRACE_LOG_API

View File

@ -1,60 +0,0 @@
#
# Copyright 2016 FUJITSU LIMITED
#
# 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.
#
# --- WARNING ---
# monasca-log-api DevStack plugin has been deprecated in Ussuri
# the code has been merged into monasca-api DevStack plugin
# the settings here apply only to stable/train and older branches
# please use settings in monasca-api for newer releases
# services
enable_service zookeeper # devstack/monasca-api/zookeeper
enable_service kibana # devstack/monasca-api/kafka
enable_service elasticsearch
enable_service monasca-log
enable_service monasca-log-api
enable_service monasca-log-persister
enable_service monasca-log-transformer
enable_service monasca-log-metrics
enable_service monasca-log-agent
# libraries/frameworks/projects monasca-log requires to install itself
KIBANA_VERSION=${KIBANA_VERSION:-4.6.3}
LOGSTASH_VERSION=${LOGSTASH_VERSION:-2.4.1}
ELASTICSEARCH_VERSION=${ELASTICSEARCH_VERSION:-2.4.6}
LOGSTASH_OUTPUT_MONASCA_VERSION=${LOGSTASH_OUTPUT_MONASCA_VERSION:-1.0.4}
NODE_JS_VERSION=${NODE_JS_VERSION:-"4.0.0"}
NVM_VERSION=${NVM_VERSION:-"0.33.5"}
# repository settings
MONASCA_LOG_API_REPO=${MONASCA_LOG_API_REPO:-${GIT_BASE}/openstack/monasca-log-api.git}
MONASCA_LOG_API_BRANCH=${MONASCA_LOG_API_BRANCH:-master}
MONASCA_LOG_API_DIR=${DEST}/monasca-log-api
MONASCA_COMMON_REPO=${MONASCA_COMMON_REPO:-${GIT_BASE}/openstack/monasca-common.git}
MONASCA_COMMON_BRANCH=${MONASCA_COMMON_BRANCH:-master}
MONASCA_COMMON_DIR=${DEST}/monasca-common
MONASCA_STATSD_REPO=${MONASCA_STATSD_REPO:-${GIT_BASE}/openstack/monasca-statsd.git}
MONASCA_STATSD_BRANCH=${MONASCA_STATSD_BRANCH:-master}
MONASCA_STATSD_DIR=${DEST}/monasca-statsd
MONASCA_KIBANA_PLUGIN_REPO=${MONASCA_KIBANA_PLUGIN_REPO:-${GIT_BASE}/openstack/monasca-kibana-plugin.git}
MONASCA_KIBANA_PLUGIN_BRANCH=${MONASCA_KIBANA_PLUGIN_BRANCH:-master}
MONASCA_KIBANA_PLUGIN_DIR=${DEST}/monasca-kibana-plugin
DOWNLOAD_FILE_TIMEOUT=${DOWNLOAD_FILE_TIMEOUT:-300}

View File

@ -1,4 +0,0 @@
{
"message":"Hello World!"
}

View File

@ -1 +0,0 @@
Hello World

View File

@ -1,22 +0,0 @@
{
"dimensions":{
"hostname":"mini-mon",
"service":"monitoring"
},
"logs":[
{
"message":"msg1",
"dimensions":{
"component":"mysql",
"path":"/var/log/mysql.log"
}
},
{
"message":"msg2",
"dimensions":{
"component":"monasca-api",
"path":"/var/log/monasca/monasca-api.log"
}
}
]
}

View File

@ -1,26 +0,0 @@
{
"dimensions":{},
"logs":[
{
"message":"msg1",
"dimensions":{
"component":"mysql",
"path":"/var/log/mysql.log"
}
},
{
"message":"msg2",
"dimensions":{
"component":"monasca-api",
"path":"/var/log/monasca/monasca-api.log"
}
},
{
"message":"msg3",
"dimensions":{
"component":"monasca-log-api",
"path":"/var/log/monasca/monasca-log-api.log"
}
}
]
}

View File

@ -1,12 +0,0 @@
{
"dimensions":{},
"logs":[
{
"message":"msg1",
"dimensions":{
"component":"mysql",
"path":"/var/log/mysql.log"
}
}
]
}

View File

@ -1 +0,0 @@
_static/*.sample

Binary file not shown.

Before

Width:  |  Height:  |  Size: 166 KiB

View File

@ -1,988 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.2" width="453.32mm" height="226.13mm" viewBox="0 0 45332 22613" preserveAspectRatio="xMidYMid" fill-rule="evenodd" stroke-width="28.222" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" xmlns:ooo="http://xml.openoffice.org/svg/export" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:presentation="http://sun.com/xmlns/staroffice/presentation" xmlns:smil="http://www.w3.org/2001/SMIL20/" xmlns:anim="urn:oasis:names:tc:opendocument:xmlns:animation:1.0" xml:space="preserve">
<defs class="ClipPathGroup">
<clipPath id="presentation_clip_path" clipPathUnits="userSpaceOnUse">
<rect x="0" y="0" width="45332" height="22613"/>
</clipPath>
<clipPath id="presentation_clip_path_shrink" clipPathUnits="userSpaceOnUse">
<rect x="45" y="22" width="45242" height="22568"/>
</clipPath>
</defs>
<defs>
<font id="EmbeddedFont_1" horiz-adv-x="2048">
<font-face font-family="Helvetica embedded" units-per-em="2048" font-weight="bold" font-style="normal" ascent="2302" descent="635"/>
<missing-glyph horiz-adv-x="2048" d="M 0,0 L 2047,0 2047,2047 0,2047 0,0 Z"/>
<glyph unicode="y" horiz-adv-x="1112" d="M 1102,1106 L 807,1106 578,301 334,1106 18,1106 430,-47 430,-53 C 430,-158 352,-238 252,-238 229,-238 213,-236 176,-225 L 176,-440 C 219,-446 244,-449 279,-449 471,-449 571,-414 647,-203 L 1102,1106 Z"/>
<glyph unicode="u" horiz-adv-x="1006" d="M 1108,0 L 1108,1106 821,1106 821,442 C 821,311 729,225 590,225 467,225 406,291 406,424 L 406,1106 119,1106 119,365 C 119,121 254,-18 489,-18 639,-18 739,37 821,145 L 821,0 1108,0 Z"/>
<glyph unicode="t" horiz-adv-x="610" d="M 616,0 L 616,201 C 588,197 571,195 551,195 475,195 457,217 457,315 L 457,893 616,893 616,1083 457,1083 457,1380 170,1380 170,1083 29,1083 29,893 170,893 170,238 C 170,63 262,-8 451,-8 514,-8 565,-2 616,0 Z"/>
<glyph unicode="s" horiz-adv-x="1033" d="M 1065,328 L 1065,342 C 1065,469 993,563 848,606 L 485,711 C 406,733 385,752 385,797 385,858 451,899 551,899 688,899 756,850 758,750 L 1034,750 C 1030,983 850,1124 553,1124 272,1124 98,983 98,756 98,621 135,547 340,483 L 682,377 C 754,354 778,332 778,301 778,233 698,207 565,207 434,207 365,231 340,350 L 59,350 C 68,109 246,-18 582,-18 893,-18 1065,104 1065,328 Z"/>
<glyph unicode="r" horiz-adv-x="662" d="M 758,831 L 758,1122 C 741,1124 731,1124 723,1124 592,1124 477,1038 416,889 L 416,1106 129,1106 129,0 416,0 416,588 C 416,756 500,840 668,840 698,840 719,838 758,831 Z"/>
<glyph unicode="q" horiz-adv-x="1059" d="M 1114,-446 L 1114,1106 827,1106 827,942 C 760,1063 657,1124 520,1124 254,1124 57,891 57,553 57,221 236,-18 518,-18 657,-18 760,27 827,147 L 827,-446 1114,-446 Z M 827,547 C 827,346 729,221 586,221 442,221 344,346 344,553 344,760 442,885 586,885 731,885 827,762 827,547 Z"/>
<glyph unicode="p" horiz-adv-x="1086" d="M 1176,553 C 1176,881 1001,1124 713,1124 573,1124 475,1065 406,942 L 406,1106 119,1106 119,-446 406,-446 406,147 C 475,25 573,-18 713,-18 979,-18 1176,217 1176,553 Z M 889,549 C 889,348 788,221 647,221 504,221 406,346 406,553 406,760 504,885 647,885 793,885 889,760 889,549 Z"/>
<glyph unicode="o" horiz-adv-x="1112" d="M 1165,545 C 1165,920 963,1124 616,1124 279,1124 72,915 72,553 72,188 279,-18 619,-18 954,-18 1165,190 1165,545 Z M 879,549 C 879,342 772,213 619,213 463,213 358,342 358,553 358,764 463,893 619,893 776,893 879,766 879,549 Z"/>
<glyph unicode="n" horiz-adv-x="1033" d="M 1118,0 L 1118,741 C 1118,985 983,1124 748,1124 598,1124 498,1069 416,946 L 416,1106 129,1106 129,0 416,0 416,664 C 416,795 508,881 647,881 770,881 831,813 831,682 L 831,0 1118,0 Z"/>
<glyph unicode="m" horiz-adv-x="1588" d="M 1688,0 L 1688,782 C 1688,997 1556,1124 1335,1124 1196,1124 1098,1075 1012,961 958,1065 848,1124 711,1124 584,1124 502,1081 408,969 L 408,1106 123,1106 123,0 410,0 410,664 C 410,799 483,881 606,881 702,881 762,825 762,737 L 762,0 1049,0 1049,664 C 1049,799 1122,881 1245,881 1341,881 1401,825 1401,737 L 1401,0 1688,0 Z"/>
<glyph unicode="l" horiz-adv-x="292" d="M 424,0 L 424,1493 137,1493 137,0 424,0 Z"/>
<glyph unicode="i" horiz-adv-x="319" d="M 424,0 L 424,1106 137,1106 137,0 424,0 Z M 428,1239 L 428,1526 141,1526 141,1239 428,1239 Z"/>
<glyph unicode="h" horiz-adv-x="980" d="M 1108,0 L 1108,741 C 1108,999 956,1124 748,1124 606,1124 504,1067 424,946 L 424,1493 137,1493 137,0 424,0 424,664 C 424,791 516,881 645,881 748,881 821,825 821,676 L 821,0 1108,0 Z"/>
<glyph unicode="g" horiz-adv-x="1059" d="M 1108,-37 L 1108,1106 836,1106 836,936 C 750,1067 655,1124 528,1124 266,1124 70,883 70,541 70,197 250,-18 522,-18 651,-18 729,20 836,127 L 836,-37 C 836,-170 735,-262 592,-262 483,-262 412,-217 389,-133 L 92,-133 C 96,-313 279,-446 582,-446 915,-446 1108,-297 1108,-37 Z M 840,545 C 840,344 735,221 586,221 451,221 356,344 356,545 356,754 451,885 590,885 733,885 840,750 840,545 Z"/>
<glyph unicode="f" horiz-adv-x="636" d="M 641,893 L 641,1083 471,1083 471,1192 C 471,1249 496,1278 549,1278 573,1278 606,1276 631,1272 L 631,1487 C 578,1491 506,1493 467,1493 276,1493 184,1403 184,1217 L 184,1083 29,1083 29,893 184,893 184,0 471,0 471,893 641,893 Z"/>
<glyph unicode="e" horiz-adv-x="1060" d="M 1075,512 C 1075,893 883,1124 557,1124 240,1124 45,909 45,539 45,184 238,-18 551,-18 799,-18 999,94 1063,311 L 780,311 C 756,231 666,201 561,201 426,201 340,262 332,477 L 1073,477 1075,512 Z M 776,668 L 336,668 C 354,821 426,905 553,905 676,905 762,825 776,668 Z"/>
<glyph unicode="d" horiz-adv-x="1059" d="M 1116,0 L 1116,1493 829,1493 829,963 C 758,1073 662,1124 524,1124 260,1124 59,885 59,551 59,238 231,-18 524,-18 662,-18 758,33 829,127 L 829,0 1116,0 Z M 829,547 C 829,346 731,221 588,221 444,221 346,348 346,551 346,756 444,885 588,885 733,885 829,758 829,547 Z"/>
<glyph unicode="c" horiz-adv-x="1033" d="M 1069,383 L 795,383 C 758,268 700,213 590,213 444,213 356,330 356,545 356,748 410,893 590,893 707,893 762,838 795,692 L 1069,692 C 1049,963 868,1124 592,1124 262,1124 70,922 70,545 70,180 260,-18 588,-18 856,-18 1042,147 1069,383 Z"/>
<glyph unicode="b" horiz-adv-x="1086" d="M 1178,539 C 1178,852 1004,1124 713,1124 575,1124 477,1073 408,963 L 408,1493 121,1493 121,0 408,0 408,127 C 477,33 573,-18 713,-18 977,-18 1178,205 1178,539 Z M 891,551 C 891,350 791,221 649,221 504,221 408,346 408,557 408,758 506,885 649,885 791,885 891,756 891,551 Z"/>
<glyph unicode="a" horiz-adv-x="1033" d="M 1073,0 L 1073,35 C 1022,82 1008,113 1008,170 L 1008,784 C 1008,1010 854,1124 555,1124 256,1124 100,997 82,741 L 358,741 C 373,856 420,893 561,893 672,893 727,856 727,782 727,666 641,678 498,653 L 383,633 C 164,594 57,500 57,299 57,84 209,-18 393,-18 516,-18 629,35 729,139 729,82 735,33 762,0 L 1073,0 Z M 727,473 C 727,307 645,213 500,213 403,213 344,250 344,332 344,416 389,446 508,469 L 606,487 C 682,502 694,506 727,522 L 727,473 Z"/>
<glyph unicode="U" horiz-adv-x="1218" d="M 1339,504 L 1339,1493 1032,1493 1032,504 C 1032,324 940,238 748,238 555,238 463,324 463,504 L 463,1493 156,1493 156,504 C 156,152 406,-25 748,-25 1090,-25 1339,152 1339,504 Z"/>
<glyph unicode="T" horiz-adv-x="1219" d="M 1225,1237 L 1225,1493 29,1493 29,1237 481,1237 481,0 788,0 788,1237 1225,1237 Z"/>
<glyph unicode="Q" horiz-adv-x="1457" d="M 1526,78 L 1362,233 C 1462,356 1526,551 1526,752 1526,1192 1243,1518 807,1518 371,1518 88,1196 88,748 88,299 373,-25 807,-25 961,-25 1075,6 1194,78 L 1370,-88 1526,78 Z M 1219,745 C 1219,623 1196,522 1151,432 L 983,592 827,426 985,276 C 938,252 870,238 805,238 559,238 395,434 395,748 395,1061 559,1255 807,1255 1057,1255 1219,1051 1219,745 Z"/>
<glyph unicode="P" horiz-adv-x="1165" d="M 1296,1030 C 1296,1329 1126,1493 815,1493 L 156,1493 156,0 463,0 463,532 846,532 C 1120,532 1296,727 1296,1030 Z M 989,1012 C 989,860 913,788 750,788 L 463,788 463,1237 750,1237 C 913,1237 989,1165 989,1012 Z"/>
<glyph unicode="M" horiz-adv-x="1457" d="M 1589,0 L 1589,1493 1126,1493 864,305 594,1493 135,1493 135,0 442,0 442,1163 711,0 1018,0 1282,1163 1282,0 1589,0 Z"/>
<glyph unicode="L" horiz-adv-x="1033" d="M 1186,0 L 1186,256 471,256 471,1493 164,1493 164,0 1186,0 Z"/>
<glyph unicode="K" horiz-adv-x="1351" d="M 1468,0 L 809,850 1405,1493 1042,1493 459,838 459,1493 152,1493 152,0 459,0 459,500 612,659 1102,0 1468,0 Z"/>
<glyph unicode="I" horiz-adv-x="345" d="M 436,0 L 436,1493 129,1493 129,0 436,0 Z"/>
<glyph unicode="E" horiz-adv-x="1138" d="M 1278,0 L 1278,256 469,256 469,643 1184,643 1184,899 469,899 469,1237 1241,1237 1241,1493 162,1493 162,0 1278,0 Z"/>
<glyph unicode="A" horiz-adv-x="1403" d="M 1440,0 L 924,1493 584,1493 53,0 367,0 467,301 1026,301 1124,0 1440,0 Z M 942,557 L 553,557 748,1141 942,557 Z"/>
<glyph unicode="4" horiz-adv-x="1060" d="M 1069,322 L 1069,559 918,559 918,1452 580,1452 49,563 49,322 631,322 631,0 918,0 918,322 1069,322 Z M 631,559 L 252,559 631,1180 631,559 Z"/>
<glyph unicode="." horiz-adv-x="345" d="M 438,0 L 438,299 131,299 131,0 438,0 Z"/>
<glyph unicode=")" horiz-adv-x="557" d="M 584,541 C 584,856 485,1139 250,1493 L 45,1493 C 262,1071 332,842 332,541 332,242 262,8 45,-410 L 250,-410 C 485,-55 584,227 584,541 Z"/>
<glyph unicode="(" horiz-adv-x="557" d="M 621,-410 C 403,12 334,242 334,543 334,842 403,1075 621,1493 L 416,1493 C 180,1139 82,856 82,543 82,227 180,-55 416,-410 L 621,-410 Z"/>
<glyph unicode=" " horiz-adv-x="556"/>
</font>
</defs>
<defs>
<font id="EmbeddedFont_2" horiz-adv-x="2048">
<font-face font-family="Liberation Sans embedded" units-per-em="2048" font-weight="bold" font-style="normal" ascent="1852" descent="423"/>
<missing-glyph horiz-adv-x="2048" d="M 0,0 L 2047,0 2047,2047 0,2047 0,0 Z"/>
<glyph unicode="y" horiz-adv-x="1139" d="M 584,241 L 834,1082 1128,1082 700,-57 C 646,-188 590,-281 532,-336 469,-395 386,-425 283,-425 216,-425 157,-421 106,-412 L 106,-212 C 141,-217 173,-220 202,-220 230,-220 255,-217 276,-211 297,-205 317,-195 334,-181 368,-153 399,-105 426,-37 L 444,11 16,1082 313,1082 584,241 Z"/>
<glyph unicode="u" horiz-adv-x="1006" d="M 408,1082 L 408,475 C 408,433 411,395 418,360 425,325 436,295 451,270 466,245 486,225 511,211 535,197 565,190 600,190 634,190 665,198 693,213 720,228 744,249 764,277 784,304 800,337 811,376 822,414 827,456 827,502 L 827,1082 1108,1082 1108,242 C 1108,219 1108,196 1109,171 1109,146 1110,122 1111,100 1112,77 1113,57 1114,40 1115,22 1115,9 1116,0 L 848,0 C 847,8 846,21 845,39 843,56 842,76 841,97 840,118 839,140 838,161 837,182 836,200 836,215 L 831,215 C 794,133 746,73 689,36 631,-1 562,-20 483,-20 418,-20 363,-9 318,12 273,33 236,63 208,100 179,137 159,180 146,231 133,282 127,336 127,395 L 127,1082 408,1082 Z"/>
<glyph unicode="t" horiz-adv-x="662" d="M 420,-18 C 337,-18 274,5 229,50 184,95 162,163 162,254 L 162,892 25,892 25,1082 176,1082 264,1336 440,1336 440,1082 645,1082 645,892 440,892 440,330 C 440,277 450,239 470,214 490,189 521,176 563,176 580,176 596,177 610,180 624,183 640,186 657,190 L 657,16 C 622,5 586,-4 547,-10 508,-15 466,-18 420,-18 Z"/>
<glyph unicode="s" horiz-adv-x="1006" d="M 1055,316 C 1055,264 1044,217 1023,176 1001,135 969,100 928,71 887,42 836,19 776,4 716,-12 648,-20 571,-20 502,-20 440,-15 385,-5 330,5 281,22 240,45 198,68 163,97 135,134 107,171 86,216 72,270 L 319,307 C 327,277 338,253 352,234 366,215 383,201 404,191 425,181 449,174 477,171 504,168 536,166 571,166 603,166 633,168 661,172 688,175 712,182 733,191 753,200 769,212 780,229 791,245 797,265 797,290 797,318 789,340 773,357 756,373 734,386 706,397 677,407 644,416 606,424 567,431 526,440 483,450 438,460 393,472 349,486 305,500 266,519 231,543 196,567 168,598 147,635 126,672 115,718 115,775 115,826 125,872 145,913 165,953 194,987 233,1016 272,1044 320,1066 377,1081 434,1096 499,1103 573,1103 632,1103 686,1098 737,1087 788,1076 833,1058 873,1035 913,1011 947,981 974,944 1001,907 1019,863 1030,811 L 781,785 C 776,811 768,833 756,850 744,867 729,880 712,890 694,900 673,907 650,911 627,914 601,916 573,916 506,916 456,908 423,891 390,874 373,845 373,805 373,780 380,761 394,746 407,731 427,719 452,710 477,700 506,692 541,685 575,678 612,669 653,659 703,648 752,636 801,622 849,607 892,588 930,563 967,538 998,505 1021,466 1044,427 1055,377 1055,316 Z"/>
<glyph unicode="r" horiz-adv-x="636" d="M 143,0 L 143,828 C 143,851 143,876 143,902 142,928 142,953 141,977 140,1000 139,1022 138,1041 137,1060 136,1073 135,1082 L 403,1082 C 404,1074 406,1060 407,1041 408,1021 410,999 411,976 412,953 414,930 415,907 416,884 416,865 416,851 L 420,851 C 434,890 448,926 462,957 476,988 493,1014 512,1036 531,1057 553,1074 580,1086 607,1097 640,1103 679,1103 696,1103 712,1102 729,1099 745,1096 757,1092 766,1088 L 766,853 C 748,857 730,861 712,864 693,867 671,868 646,868 576,868 522,840 483,783 444,726 424,642 424,531 L 424,0 143,0 Z"/>
<glyph unicode="p" horiz-adv-x="1033" d="M 1167,546 C 1167,464 1159,388 1143,319 1126,250 1101,190 1067,140 1033,90 990,51 938,23 885,-6 823,-20 752,-20 720,-20 688,-17 657,-10 625,-3 595,8 566,23 537,38 511,57 487,82 462,106 441,136 424,172 L 418,172 C 419,169 419,160 420,147 421,134 421,118 422,101 423,83 423,64 424,45 424,25 424,7 424,-10 L 424,-425 143,-425 143,833 C 143,888 142,938 141,981 139,1024 137,1058 135,1082 L 408,1082 C 409,1077 411,1068 413,1055 414,1042 416,1026 417,1009 418,992 418,974 419,955 420,936 420,920 420,906 L 424,906 C 458,977 505,1028 564,1059 623,1090 692,1105 770,1105 839,1105 898,1091 948,1063 998,1035 1039,996 1072,947 1104,898 1128,839 1144,771 1159,702 1167,627 1167,546 Z M 874,546 C 874,669 855,761 818,821 781,880 725,910 651,910 623,910 595,904 568,893 540,881 515,861 494,833 472,804 454,766 441,719 427,671 420,611 420,538 420,467 427,409 440,362 453,315 471,277 493,249 514,221 539,201 566,190 593,178 621,172 649,172 685,172 717,179 745,194 773,208 797,230 816,261 835,291 849,330 859,377 869,424 874,481 874,546 Z"/>
<glyph unicode="o" horiz-adv-x="1113" d="M 1171,542 C 1171,459 1160,384 1137,315 1114,246 1079,187 1033,138 987,88 930,49 861,22 792,-6 712,-20 621,-20 533,-20 455,-6 388,21 321,48 264,87 219,136 173,185 138,245 115,314 92,383 80,459 80,542 80,623 91,697 114,766 136,834 170,893 215,943 260,993 317,1032 386,1060 455,1088 535,1102 627,1102 724,1102 807,1088 876,1060 945,1032 1001,993 1045,944 1088,894 1120,835 1141,767 1161,698 1171,623 1171,542 Z M 877,542 C 877,671 856,764 814,822 772,880 711,909 631,909 548,909 485,880 441,821 397,762 375,669 375,542 375,477 381,422 393,375 404,328 421,290 442,260 463,230 489,208 519,194 549,179 582,172 618,172 659,172 696,179 729,194 761,208 788,230 810,260 832,290 849,328 860,375 871,422 877,477 877,542 Z"/>
<glyph unicode="n" horiz-adv-x="1007" d="M 844,0 L 844,607 C 844,649 841,688 834,723 827,758 816,788 801,813 786,838 766,857 741,871 716,885 686,892 651,892 617,892 586,885 559,870 531,855 507,833 487,806 467,778 452,745 441,707 430,668 424,626 424,580 L 424,0 143,0 143,840 C 143,863 143,887 143,912 142,937 142,960 141,983 140,1005 139,1025 138,1043 137,1060 136,1073 135,1082 L 403,1082 C 404,1074 406,1061 407,1044 408,1026 410,1006 411,985 412,964 414,942 415,921 416,900 416,882 416,867 L 420,867 C 458,950 506,1010 563,1047 620,1084 689,1103 768,1103 833,1103 889,1092 934,1071 979,1050 1015,1020 1044,983 1072,946 1092,902 1105,851 1118,800 1124,746 1124,687 L 1124,0 844,0 Z"/>
<glyph unicode="m" horiz-adv-x="1562" d="M 780,0 L 780,607 C 780,649 777,688 772,723 766,758 757,788 744,813 731,838 714,857 693,871 672,885 646,892 616,892 587,892 561,885 538,870 515,855 495,833 478,806 461,778 447,745 438,707 429,668 424,626 424,580 L 424,0 143,0 143,840 C 143,863 143,887 143,912 142,937 142,960 141,983 140,1005 139,1025 138,1043 137,1060 136,1073 135,1082 L 403,1082 C 404,1074 406,1061 407,1044 408,1026 410,1006 411,985 412,964 414,942 415,921 416,900 416,882 416,867 L 420,867 C 455,950 498,1010 550,1047 601,1084 663,1103 735,1103 818,1103 884,1083 935,1043 985,1002 1019,944 1036,867 L 1042,867 C 1061,912 1082,949 1105,979 1127,1009 1152,1033 1179,1052 1206,1070 1235,1083 1267,1091 1298,1099 1333,1103 1370,1103 1429,1103 1480,1092 1521,1071 1562,1050 1595,1020 1621,983 1646,946 1665,902 1677,851 1688,800 1694,746 1694,687 L 1694,0 1415,0 1415,607 C 1415,649 1412,688 1407,723 1401,758 1392,788 1379,813 1366,838 1349,857 1328,871 1307,885 1281,892 1251,892 1223,892 1198,885 1175,871 1152,856 1132,836 1115,810 1098,783 1084,752 1075,715 1066,678 1060,638 1059,593 L 1059,0 780,0 Z"/>
<glyph unicode="l" horiz-adv-x="292" d="M 143,0 L 143,1484 424,1484 424,0 143,0 Z"/>
<glyph unicode="k" horiz-adv-x="1007" d="M 834,0 L 545,490 424,406 424,0 143,0 143,1484 424,1484 424,634 810,1082 1112,1082 732,660 1141,0 834,0 Z"/>
<glyph unicode="i" horiz-adv-x="292" d="M 143,1277 L 143,1484 424,1484 424,1277 143,1277 Z M 143,0 L 143,1082 424,1082 424,0 143,0 Z"/>
<glyph unicode="h" horiz-adv-x="1007" d="M 420,866 C 458,949 506,1009 563,1046 620,1083 689,1102 768,1102 833,1102 889,1091 934,1070 979,1049 1015,1019 1044,982 1072,945 1092,901 1105,850 1118,799 1124,745 1124,686 L 1124,0 844,0 844,606 C 844,648 841,687 834,722 827,757 816,787 801,812 786,837 766,856 741,870 716,884 686,891 651,891 617,891 586,884 559,869 531,854 507,832 487,805 467,777 452,744 441,706 430,667 424,625 424,579 L 424,0 143,0 143,1484 424,1484 424,1079 C 424,1058 424,1036 423,1015 422,993 422,973 421,954 420,935 419,917 418,902 417,887 417,875 416,866 L 420,866 Z"/>
<glyph unicode="g" horiz-adv-x="1033" d="M 596,-434 C 525,-434 462,-427 408,-413 353,-398 307,-378 269,-353 230,-327 200,-296 177,-261 154,-225 138,-186 129,-143 L 410,-110 C 420,-153 442,-187 475,-212 508,-237 551,-249 604,-249 637,-249 668,-244 696,-235 723,-226 747,-210 767,-188 786,-165 802,-136 813,-99 824,-62 829,-17 829,37 829,56 829,75 829,94 829,113 829,131 830,147 831,166 831,184 831,201 L 829,201 C 796,131 751,80 692,49 633,18 562,2 481,2 412,2 353,16 304,43 254,70 213,107 180,156 147,204 123,262 108,329 92,396 84,469 84,550 84,633 92,709 109,777 126,844 151,902 186,951 220,1000 263,1037 316,1064 368,1090 430,1103 502,1103 574,1103 639,1088 696,1057 753,1026 797,977 829,908 L 834,908 C 834,922 835,938 836,957 837,975 838,993 839,1010 840,1027 842,1042 844,1055 845,1068 847,1077 848,1082 L 1114,1082 C 1113,1058 1111,1024 1110,981 1109,938 1108,888 1108,832 L 1108,33 C 1108,-46 1097,-114 1074,-173 1051,-231 1018,-279 975,-318 931,-357 877,-386 814,-405 750,-424 677,-434 596,-434 Z M 831,556 C 831,624 824,681 811,726 798,771 780,808 759,835 738,862 713,882 686,893 658,904 630,910 602,910 566,910 534,903 507,889 479,875 455,853 436,824 417,795 402,757 392,712 382,667 377,613 377,550 377,433 396,345 433,286 470,227 526,197 600,197 628,197 656,203 684,214 711,225 736,244 758,272 780,299 798,336 811,382 824,428 831,486 831,556 Z"/>
<glyph unicode="f" horiz-adv-x="663" d="M 473,892 L 473,0 193,0 193,892 35,892 35,1082 193,1082 193,1195 C 193,1236 198,1275 208,1310 218,1345 235,1375 259,1401 283,1427 315,1447 356,1462 397,1477 447,1484 508,1484 540,1484 572,1482 603,1479 634,1476 661,1472 686,1468 L 686,1287 C 674,1290 661,1292 646,1294 631,1295 617,1296 604,1296 578,1296 557,1293 540,1288 523,1283 509,1275 500,1264 490,1253 483,1240 479,1224 475,1207 473,1188 473,1167 L 473,1082 686,1082 686,892 473,892 Z"/>
<glyph unicode="e" horiz-adv-x="1007" d="M 586,-20 C 508,-20 438,-8 376,15 313,38 260,73 216,120 172,167 138,226 115,297 92,368 80,451 80,546 80,649 94,736 122,807 149,878 187,935 234,979 281,1022 335,1054 396,1073 457,1092 522,1102 590,1102 675,1102 748,1087 809,1058 869,1028 918,986 957,933 996,880 1024,816 1042,742 1060,667 1069,585 1069,495 L 1069,487 375,487 C 375,442 379,400 387,361 395,322 408,288 426,260 444,231 467,209 496,193 525,176 559,168 600,168 649,168 690,179 721,200 752,221 775,253 788,297 L 1053,274 C 1041,243 1024,211 1003,176 981,141 952,110 916,81 880,52 835,28 782,9 728,-10 663,-20 586,-20 Z M 586,925 C 557,925 531,920 506,911 481,901 459,886 441,865 422,844 407,816 396,783 385,750 378,710 377,663 L 797,663 C 792,750 771,816 734,860 697,903 648,925 586,925 Z"/>
<glyph unicode="c" horiz-adv-x="1007" d="M 594,-20 C 508,-20 433,-7 369,20 304,47 251,84 208,133 165,182 133,240 112,309 91,377 80,452 80,535 80,625 92,705 115,776 138,846 172,905 216,954 260,1002 314,1039 379,1064 443,1089 516,1102 598,1102 668,1102 730,1093 785,1074 839,1055 886,1030 925,998 964,965 996,927 1021,883 1045,839 1062,792 1071,741 L 788,727 C 780,782 760,827 728,860 696,893 651,909 592,909 517,909 462,878 427,816 392,754 375,664 375,546 375,297 449,172 596,172 649,172 694,189 730,223 766,256 788,306 797,373 L 1079,360 C 1072,310 1057,262 1034,217 1010,171 978,131 938,96 897,61 848,33 791,12 734,-9 668,-20 594,-20 Z"/>
<glyph unicode="b" horiz-adv-x="1033" d="M 1167,545 C 1167,463 1159,388 1143,319 1126,250 1101,190 1067,140 1033,89 990,50 938,22 885,-6 823,-20 752,-20 720,-20 688,-17 656,-10 624,-3 594,8 565,23 536,38 510,58 486,83 462,108 441,138 424,174 L 422,174 C 422,160 422,144 421,126 420,108 418,91 417,74 416,57 414,41 413,28 411,15 409,5 408,0 L 135,0 C 137,23 139,57 141,100 142,143 143,192 143,247 L 143,1484 424,1484 424,1070 C 424,1049 424,1028 424,1008 423,987 423,968 422,951 421,931 421,912 420,894 L 424,894 C 458,969 505,1022 564,1054 623,1086 692,1102 770,1102 839,1102 899,1088 949,1061 999,1033 1040,994 1073,945 1105,895 1129,836 1144,768 1159,700 1167,626 1167,545 Z M 874,545 C 874,668 856,759 820,818 784,877 728,907 653,907 624,907 596,901 568,890 540,879 515,859 493,831 471,802 453,764 440,717 427,669 420,609 420,536 420,465 427,407 440,360 453,313 471,276 492,248 513,220 538,200 566,189 594,178 622,172 651,172 722,172 777,202 816,261 855,320 874,414 874,545 Z"/>
<glyph unicode="a" horiz-adv-x="1112" d="M 393,-20 C 341,-20 295,-13 254,2 213,16 178,37 149,65 120,92 98,126 83,167 68,208 60,254 60,306 60,370 71,424 94,468 116,511 146,547 185,574 224,601 269,620 321,633 373,645 428,651 487,652 L 720,656 720,711 C 720,750 717,783 710,810 703,836 692,857 679,874 666,891 649,903 630,910 610,917 587,920 562,920 539,920 518,918 500,913 481,908 465,900 452,889 439,877 428,861 420,842 411,822 405,797 402,767 L 109,781 C 117,828 132,872 153,911 174,950 204,983 242,1012 279,1041 326,1063 381,1079 436,1094 500,1102 574,1102 641,1102 701,1094 754,1077 807,1060 851,1036 888,1003 925,970 953,929 972,881 991,833 1001,777 1001,714 L 1001,320 C 1001,295 1002,272 1005,252 1007,232 1011,215 1018,202 1024,188 1033,178 1045,171 1056,164 1071,160 1090,160 1111,160 1132,162 1152,166 L 1152,14 C 1135,10 1120,6 1107,3 1094,0 1080,-3 1067,-5 1054,-7 1040,-9 1025,-10 1010,-11 992,-12 972,-12 901,-12 849,5 816,40 782,75 762,126 755,193 L 749,193 C 712,126 664,73 606,36 547,-1 476,-20 393,-20 Z M 720,501 L 576,499 C 546,498 518,495 491,492 464,488 440,480 420,469 399,457 383,440 371,418 359,396 353,366 353,328 353,277 365,239 389,214 412,189 444,176 483,176 519,176 552,184 581,199 610,214 635,235 656,260 676,285 692,313 703,346 714,379 720,412 720,446 L 720,501 Z"/>
<glyph unicode="U" horiz-adv-x="1244" d="M 723,-20 C 635,-20 554,-9 481,12 408,33 345,65 292,110 239,154 197,211 168,280 138,349 123,432 123,528 L 123,1409 418,1409 418,551 C 418,492 425,441 440,398 455,355 476,319 503,292 530,264 563,244 602,231 641,218 684,211 731,211 779,211 823,218 864,232 904,245 939,266 968,295 997,324 1019,360 1035,404 1051,448 1059,500 1059,561 L 1059,1409 1354,1409 1354,543 C 1354,446 1338,363 1307,292 1276,221 1232,163 1176,117 1120,70 1054,36 977,14 900,-9 815,-20 723,-20 Z"/>
<glyph unicode="T" horiz-adv-x="1245" d="M 773,1181 L 773,0 478,0 478,1181 23,1181 23,1409 1229,1409 1229,1181 773,1181 Z"/>
<glyph unicode="S" horiz-adv-x="1244" d="M 1286,406 C 1286,342 1274,284 1251,232 1228,179 1192,134 1143,97 1094,60 1031,31 955,11 878,-10 787,-20 682,-20 589,-20 506,-12 435,5 364,22 303,46 252,79 201,112 159,152 128,201 96,249 73,304 59,367 L 344,414 C 352,383 364,354 379,328 394,302 416,280 443,261 470,242 503,227 544,217 584,206 633,201 690,201 790,201 867,216 920,247 973,277 999,324 999,389 999,428 988,459 967,484 946,509 917,529 882,545 847,561 806,574 760,585 714,596 666,606 616,616 576,625 536,635 496,645 456,655 418,667 382,681 345,695 311,712 280,731 249,750 222,774 199,803 176,831 158,864 145,902 132,940 125,985 125,1036 125,1106 139,1166 167,1216 195,1266 234,1307 284,1339 333,1370 392,1393 461,1408 530,1423 605,1430 686,1430 778,1430 857,1423 923,1409 988,1394 1043,1372 1088,1343 1132,1314 1167,1277 1193,1233 1218,1188 1237,1136 1249,1077 L 963,1038 C 948,1099 919,1144 874,1175 829,1206 764,1221 680,1221 628,1221 585,1217 551,1208 516,1199 489,1186 469,1171 448,1156 434,1138 425,1118 416,1097 412,1076 412,1053 412,1018 420,990 437,968 454,945 477,927 507,912 537,897 573,884 615,874 656,863 702,853 752,842 796,833 840,823 883,813 926,802 968,790 1007,776 1046,762 1083,745 1117,725 1151,705 1181,681 1206,652 1231,623 1250,588 1265,548 1279,508 1286,461 1286,406 Z"/>
<glyph unicode="P" horiz-adv-x="1165" d="M 1296,963 C 1296,902 1286,844 1266,788 1245,731 1214,681 1172,638 1130,595 1077,560 1012,535 947,509 871,496 782,496 L 432,496 432,0 137,0 137,1409 770,1409 C 860,1409 938,1398 1004,1377 1070,1355 1125,1324 1168,1285 1211,1246 1244,1199 1265,1144 1286,1089 1296,1029 1296,963 Z M 999,958 C 999,1031 977,1086 934,1124 890,1161 824,1180 737,1180 L 432,1180 432,723 745,723 C 789,723 827,729 859,740 890,751 917,767 938,788 959,809 974,834 984,863 994,892 999,923 999,958 Z"/>
<glyph unicode="O" horiz-adv-x="1430" d="M 1507,711 C 1507,601 1491,501 1458,411 1425,321 1378,244 1317,180 1256,116 1181,67 1093,32 1004,-3 904,-20 793,-20 675,-20 572,-2 484,35 395,71 321,122 262,187 203,252 158,329 129,418 99,507 84,605 84,711 84,821 100,920 131,1009 162,1098 207,1173 268,1236 328,1298 402,1346 491,1380 579,1413 680,1430 795,1430 910,1430 1011,1413 1100,1379 1188,1345 1262,1297 1323,1234 1383,1171 1429,1096 1460,1008 1491,919 1507,820 1507,711 Z M 1206,711 C 1206,785 1197,852 1180,912 1162,971 1136,1022 1101,1065 1066,1108 1024,1141 973,1164 922,1187 862,1198 795,1198 726,1198 666,1187 615,1164 563,1141 520,1108 485,1065 450,1022 424,971 407,912 390,852 381,785 381,711 381,638 390,571 408,510 425,449 451,396 486,352 521,308 564,274 615,249 666,224 726,212 793,212 865,212 927,225 979,250 1031,275 1074,309 1108,354 1141,398 1166,451 1182,512 1198,573 1206,639 1206,711 Z"/>
<glyph unicode="N" horiz-adv-x="1218" d="M 995,0 L 381,1085 C 384,1056 387,1026 390,997 393,972 395,944 397,915 398,886 399,858 399,831 L 399,0 137,0 137,1409 474,1409 1097,315 C 1094,343 1091,372 1088,403 1085,429 1083,458 1082,491 1080,524 1079,557 1079,590 L 1079,1409 1341,1409 1341,0 995,0 Z"/>
<glyph unicode="K" horiz-adv-x="1324" d="M 1112,0 L 606,647 432,514 432,0 137,0 137,1409 432,1409 432,770 1067,1409 1411,1409 809,813 1460,0 1112,0 Z"/>
<glyph unicode="I" horiz-adv-x="319" d="M 137,0 L 137,1409 432,1409 432,0 137,0 Z"/>
<glyph unicode="E" horiz-adv-x="1165" d="M 137,0 L 137,1409 1245,1409 1245,1181 432,1181 432,827 1184,827 1184,599 432,599 432,228 1286,228 1286,0 137,0 Z"/>
<glyph unicode=":" horiz-adv-x="319" d="M 197,752 L 197,1034 485,1034 485,752 197,752 Z M 197,0 L 197,281 485,281 485,0 197,0 Z"/>
<glyph unicode=" " horiz-adv-x="556"/>
</font>
</defs>
<defs>
<font id="EmbeddedFont_3" horiz-adv-x="2048">
<font-face font-family="Liberation Sans embedded" units-per-em="2048" font-weight="bold" font-style="italic" ascent="1852" descent="423"/>
<missing-glyph horiz-adv-x="2048" d="M 0,0 L 2047,0 2047,2047 0,2047 0,0 Z"/>
<glyph unicode="v" horiz-adv-x="1139" d="M 622,0 L 286,0 110,1082 399,1082 470,477 C 473,457 475,435 477,411 479,387 481,363 483,339 485,315 487,292 489,269 490,246 491,226 492,208 499,225 508,245 518,268 527,291 538,314 549,338 560,362 571,386 582,409 593,432 604,454 614,474 L 930,1082 1232,1082 622,0 Z"/>
<glyph unicode="t" horiz-adv-x="689" d="M 560,8 C 535,1 507,-5 476,-10 445,-14 411,-16 376,-16 337,-16 301,-11 269,-2 237,7 210,21 187,40 164,59 147,82 135,111 122,139 116,172 116,209 116,239 118,268 122,297 125,325 129,348 132,366 L 234,892 86,892 123,1082 285,1082 422,1336 598,1336 550,1082 752,1082 717,892 512,892 408,357 C 405,344 403,328 400,309 397,290 396,273 397,260 398,232 407,211 423,198 438,184 459,177 484,177 500,177 516,178 533,181 549,183 569,186 592,190 L 560,8 Z"/>
<glyph unicode="s" horiz-adv-x="1086" d="M 1000,334 C 1000,275 989,223 967,179 944,134 912,97 869,68 826,39 773,17 711,2 648,-13 577,-20 497,-20 363,-20 257,4 180,51 103,98 50,172 23,271 L 274,307 C 281,283 290,262 302,245 314,227 330,212 349,201 368,189 392,180 420,175 447,169 480,166 517,166 550,166 580,169 607,174 634,179 657,187 677,198 696,209 712,223 723,240 734,257 739,278 739,302 739,323 735,341 726,355 717,368 703,380 685,390 666,399 643,408 615,416 586,423 553,431 515,439 462,451 414,465 370,482 325,499 287,520 255,546 223,571 198,602 180,639 162,675 153,718 153,769 153,829 166,880 191,922 216,963 250,997 294,1024 337,1050 388,1069 447,1081 506,1093 569,1099 637,1099 699,1099 755,1094 805,1085 854,1075 897,1059 933,1036 969,1013 999,984 1022,947 1045,910 1060,865 1069,811 L 818,782 C 807,828 785,861 752,882 719,903 675,913 618,913 589,913 563,911 538,908 513,904 491,897 473,888 454,879 440,866 429,851 418,836 413,816 413,793 413,772 419,754 432,740 445,725 462,713 485,703 508,692 535,683 566,676 597,668 631,660 668,651 715,640 758,627 799,612 839,597 874,577 904,553 934,528 958,498 975,463 992,428 1000,385 1000,334 Z"/>
<glyph unicode="r" horiz-adv-x="875" d="M 844,853 C 829,856 812,860 795,863 778,866 756,868 730,868 648,868 581,839 530,781 478,723 440,634 417,514 L 316,0 35,0 196,830 C 201,853 205,877 209,900 213,923 217,946 221,968 224,990 228,1011 231,1031 234,1050 236,1067 238,1082 L 506,1082 C 504,1067 502,1050 500,1030 497,1010 495,990 492,969 489,948 487,929 484,910 481,891 478,874 476,861 L 480,861 C 503,902 525,938 548,969 570,999 593,1024 618,1044 642,1063 668,1078 696,1088 723,1097 754,1102 787,1102 795,1102 804,1102 814,1101 823,1100 833,1098 843,1097 852,1096 861,1094 870,1093 878,1091 885,1089 890,1088 L 844,853 Z"/>
<glyph unicode="o" horiz-adv-x="1139" d="M 1185,683 C 1185,574 1169,477 1136,390 1103,303 1058,229 1000,168 942,107 873,61 794,29 715,-4 628,-20 535,-20 464,-20 399,-10 341,10 283,29 233,58 192,96 151,133 119,179 97,234 74,288 63,350 63,419 63,522 79,616 110,700 141,784 184,856 241,915 298,974 365,1020 444,1053 523,1085 609,1101 704,1101 783,1101 852,1092 912,1073 972,1054 1022,1027 1063,991 1103,955 1133,911 1154,860 1175,808 1185,749 1185,683 Z M 891,662 C 891,706 886,744 877,775 867,806 853,832 835,852 817,871 795,886 770,895 744,904 715,909 683,909 654,909 624,906 594,899 564,892 536,877 509,855 482,833 457,802 435,761 412,720 393,667 378,600 371,568 366,538 363,510 360,481 358,455 358,431 358,383 363,343 374,310 384,277 398,251 417,230 436,209 458,195 483,186 508,177 536,172 566,172 596,172 626,175 655,182 684,189 712,203 739,225 766,246 790,277 812,318 834,358 853,412 868,480 875,515 881,547 884,576 887,605 890,633 891,662 Z"/>
<glyph unicode="k" horiz-adv-x="1219" d="M 728,0 L 540,497 400,422 315,0 35,0 323,1484 604,1484 437,634 902,1082 1224,1082 751,660 1026,0 728,0 Z"/>
<glyph unicode="h" horiz-adv-x="1139" d="M 601,1484 L 522,1079 C 519,1065 516,1050 513,1034 510,1017 506,1001 503,985 499,969 495,953 492,938 489,923 486,909 483,897 L 486,897 C 506,925 528,951 553,976 577,1001 604,1022 634,1041 664,1060 698,1074 735,1085 772,1096 813,1101 859,1101 960,1101 1037,1077 1088,1028 1139,979 1165,909 1165,817 1165,805 1164,791 1163,776 1161,761 1159,746 1157,731 1155,716 1153,701 1151,688 1148,674 1146,662 1144,653 L 1017,0 738,0 856,595 C 859,608 862,622 865,637 868,652 870,668 873,683 876,698 878,713 880,727 881,740 882,751 882,760 882,802 869,834 844,856 818,878 780,889 730,889 699,889 667,882 636,869 605,856 576,837 549,812 522,787 498,758 478,723 457,688 443,649 435,606 L 317,0 35,0 321,1484 601,1484 Z"/>
<glyph unicode="g" horiz-adv-x="1244" d="M 431,-425 C 361,-425 300,-419 249,-407 198,-394 154,-376 119,-352 84,-328 56,-298 36,-264 15,-228 1,-188 -7,-142 L 276,-112 C 285,-156 306,-188 337,-209 368,-229 411,-239 464,-239 503,-239 536,-234 565,-224 594,-213 619,-197 640,-176 661,-154 678,-126 693,-93 707,-59 719,-19 730,27 734,46 738,66 742,87 745,107 749,126 752,143 755,163 758,182 761,201 L 759,201 C 740,174 721,148 700,123 679,98 654,75 627,56 599,37 567,21 531,10 495,-2 453,-8 405,-8 352,-8 305,1 263,19 220,37 185,62 156,94 127,126 104,164 89,209 73,254 65,303 65,356 65,389 67,424 70,461 73,498 78,538 86,580 120,754 177,884 258,971 338,1058 447,1101 586,1101 624,1101 660,1096 695,1087 729,1078 760,1064 787,1047 814,1029 838,1007 858,982 877,956 892,926 901,893 L 903,893 C 906,910 911,930 916,950 921,971 925,991 930,1010 935,1029 939,1046 943,1059 947,1073 950,1080 951,1080 L 1216,1080 C 1215,1074 1212,1064 1209,1049 1206,1034 1202,1017 1197,997 1192,976 1188,954 1183,929 1178,904 1172,878 1167,851 L 1002,9 C 987,-62 966,-126 939,-180 912,-234 876,-279 831,-316 786,-352 730,-379 665,-398 600,-416 522,-425 431,-425 Z M 833,548 C 838,571 841,596 843,621 845,646 846,668 846,686 846,724 841,757 831,785 821,812 807,835 790,854 772,873 751,887 727,896 702,905 676,909 648,909 614,909 583,904 556,894 528,883 503,866 482,841 460,816 441,782 424,740 407,697 393,644 381,581 375,548 370,515 366,482 361,449 359,421 359,396 359,327 374,277 404,245 433,213 476,197 532,197 561,197 591,204 622,217 653,230 682,250 709,279 736,307 761,343 783,388 804,432 821,485 833,548 Z"/>
<glyph unicode="f" horiz-adv-x="821" d="M 528,892 L 354,0 74,0 248,892 90,892 127,1082 285,1082 307,1195 C 316,1240 329,1281 347,1317 364,1353 389,1383 420,1408 451,1433 489,1452 534,1465 579,1478 634,1484 698,1484 728,1484 757,1482 784,1479 811,1475 834,1471 853,1467 L 817,1286 C 811,1287 804,1289 796,1290 787,1291 779,1292 770,1293 761,1294 752,1294 743,1295 734,1296 727,1296 721,1296 676,1296 644,1285 624,1264 604,1243 590,1210 581,1167 L 565,1082 778,1082 741,892 528,892 Z"/>
<glyph unicode="e" horiz-adv-x="1033" d="M 358,476 C 355,461 354,447 353,432 352,417 351,402 351,387 351,316 367,262 398,225 429,187 474,168 535,168 563,168 588,172 610,181 632,190 652,202 669,217 686,232 702,249 715,270 728,291 739,313 748,337 L 993,263 C 973,220 950,182 925,147 900,112 869,82 832,57 795,32 751,13 700,0 649,-13 587,-20 516,-20 443,-20 378,-10 322,11 265,32 218,61 180,99 141,137 112,183 93,237 73,291 63,351 63,418 63,527 78,624 107,709 136,794 176,865 228,924 279,982 341,1026 412,1057 483,1087 561,1102 646,1102 721,1102 785,1092 840,1072 895,1052 940,1024 976,988 1012,951 1039,908 1056,858 1073,807 1082,752 1082,691 1082,661 1080,627 1076,588 1071,549 1065,511 1058,476 L 358,476 Z M 822,663 C 823,674 824,683 825,692 825,701 825,710 825,719 825,790 809,842 776,875 743,908 699,924 646,924 623,924 599,920 574,913 549,906 524,892 501,873 477,853 456,826 437,793 418,759 402,716 391,663 L 822,663 Z"/>
<glyph unicode="a" horiz-adv-x="1086" d="M 1065,12 C 1037,1 1009,-5 980,-7 951,-9 922,-10 892,-10 825,-10 774,4 738,32 702,60 684,97 684,143 684,153 684,164 685,175 686,186 687,196 689,207 L 683,207 C 660,172 637,140 614,112 591,84 565,60 537,41 508,21 476,6 441,-5 406,-15 364,-20 317,-20 265,-20 220,-12 182,5 143,22 111,44 86,72 61,99 42,131 29,167 16,203 10,240 10,278 10,332 18,379 33,418 48,457 68,491 94,519 120,547 151,570 186,588 221,605 258,619 298,629 338,639 380,646 423,650 466,654 509,656 551,657 L 742,660 750,696 C 755,716 758,734 760,749 762,764 763,778 763,791 763,835 752,867 729,888 706,909 675,919 636,919 617,919 597,918 576,915 555,912 536,906 518,897 499,887 483,873 468,854 453,835 441,809 433,777 L 170,808 C 181,853 198,893 222,929 246,965 277,996 316,1022 355,1047 401,1067 455,1081 508,1095 570,1102 641,1102 779,1102 880,1078 945,1029 1009,980 1041,906 1041,807 1041,786 1038,762 1033,733 1028,704 1022,677 1017,650 L 946,297 C 944,286 942,274 941,261 939,248 938,236 938,225 938,209 941,197 948,188 955,179 962,173 971,169 980,165 988,163 997,162 1006,161 1012,160 1017,160 1026,160 1035,160 1044,161 1052,162 1064,164 1079,167 L 1065,12 Z M 711,502 L 549,502 C 471,502 410,487 365,456 320,425 297,382 297,325 297,299 301,277 309,258 317,239 328,223 341,211 354,199 370,190 388,185 405,179 424,176 443,176 462,176 484,180 508,187 531,195 555,208 578,226 601,244 622,268 642,298 662,328 678,366 689,410 L 711,502 Z"/>
<glyph unicode="L" horiz-adv-x="1113" d="M 36,0 L 309,1409 604,1409 375,228 1131,228 1086,0 36,0 Z"/>
<glyph unicode="K" horiz-adv-x="1589" d="M 995,0 L 640,640 429,517 328,0 36,0 309,1409 604,1409 474,770 1234,1409 1603,1409 856,793 1321,0 995,0 Z"/>
<glyph unicode="B" horiz-adv-x="1377" d="M 310,1409 L 894,1409 C 981,1409 1057,1402 1121,1387 1184,1372 1237,1351 1279,1323 1321,1295 1352,1261 1373,1221 1393,1180 1403,1134 1403,1083 1403,1034 1395,991 1380,953 1365,914 1343,881 1315,853 1286,824 1252,801 1212,782 1172,763 1128,748 1079,738 1126,730 1168,717 1204,698 1240,679 1270,657 1295,630 1319,603 1337,572 1350,539 1362,505 1368,469 1368,431 1368,348 1351,278 1318,223 1284,168 1239,124 1182,91 1125,58 1058,34 982,21 906,7 826,0 741,0 L 36,0 310,1409 Z M 494,841 L 788,841 C 846,841 896,845 937,852 978,859 1011,871 1037,887 1062,903 1081,924 1093,949 1104,974 1110,1003 1110,1038 1110,1067 1105,1092 1094,1112 1083,1131 1067,1147 1046,1159 1025,1170 999,1178 968,1183 937,1188 901,1190 862,1190 L 561,1190 494,841 Z M 373,219 L 701,219 C 764,219 819,222 866,229 913,236 951,247 982,264 1012,281 1035,303 1050,331 1065,359 1072,394 1072,437 1072,497 1049,543 1004,575 959,607 885,623 782,623 L 452,623 373,219 Z"/>
<glyph unicode="/" horiz-adv-x="847" d="M -76,-41 L 511,1484 749,1484 166,-41 -76,-41 Z"/>
<glyph unicode=" " horiz-adv-x="556"/>
</font>
</defs>
<defs class="TextShapeIndex">
<g ooo:slide="id1" ooo:id-list="id3 id4 id5 id6 id7 id8 id9 id10 id11 id12 id13 id14 id15 id16 id17 id18 id19 id20 id21 id22 id23 id24 id25 id26 id27 id28 id29 id30 id31 id32 id33 id34 id35 id36 id37 id38 id39 id40 id41 id42 id43 id44 id45 id46 id47 id48 id49 id50 id51 id52 id53 id54 id55 id56 id57 id58 id59 id60 id61 id62 id63 id64 id65 id66 id67 id68 id69 id70 id71 id72 id73 id74 id75 id76"/>
</defs>
<defs class="EmbeddedBulletChars">
<g id="bullet-char-template-57356" transform="scale(0.00048828125,-0.00048828125)">
<path d="M 580,1141 L 1163,571 580,0 -4,571 580,1141 Z"/>
</g>
<g id="bullet-char-template-57354" transform="scale(0.00048828125,-0.00048828125)">
<path d="M 8,1128 L 1137,1128 1137,0 8,0 8,1128 Z"/>
</g>
<g id="bullet-char-template-10146" transform="scale(0.00048828125,-0.00048828125)">
<path d="M 174,0 L 602,739 174,1481 1456,739 174,0 Z M 1358,739 L 309,1346 659,739 1358,739 Z"/>
</g>
<g id="bullet-char-template-10132" transform="scale(0.00048828125,-0.00048828125)">
<path d="M 2015,739 L 1276,0 717,0 1260,543 174,543 174,936 1260,936 717,1481 1274,1481 2015,739 Z"/>
</g>
<g id="bullet-char-template-10007" transform="scale(0.00048828125,-0.00048828125)">
<path d="M 0,-2 C -7,14 -16,27 -25,37 L 356,567 C 262,823 215,952 215,954 215,979 228,992 255,992 264,992 276,990 289,987 310,991 331,999 354,1012 L 381,999 492,748 772,1049 836,1024 860,1049 C 881,1039 901,1025 922,1006 886,937 835,863 770,784 769,783 710,716 594,584 L 774,223 C 774,196 753,168 711,139 L 727,119 C 717,90 699,76 672,76 641,76 570,178 457,381 L 164,-76 C 142,-110 111,-127 72,-127 30,-127 9,-110 8,-76 1,-67 -2,-52 -2,-32 -2,-23 -1,-13 0,-2 Z"/>
</g>
<g id="bullet-char-template-10004" transform="scale(0.00048828125,-0.00048828125)">
<path d="M 285,-33 C 182,-33 111,30 74,156 52,228 41,333 41,471 41,549 55,616 82,672 116,743 169,778 240,778 293,778 328,747 346,684 L 369,508 C 377,444 397,411 428,410 L 1163,1116 C 1174,1127 1196,1133 1229,1133 1271,1133 1292,1118 1292,1087 L 1292,965 C 1292,929 1282,901 1262,881 L 442,47 C 390,-6 338,-33 285,-33 Z"/>
</g>
<g id="bullet-char-template-9679" transform="scale(0.00048828125,-0.00048828125)">
<path d="M 813,0 C 632,0 489,54 383,161 276,268 223,411 223,592 223,773 276,916 383,1023 489,1130 632,1184 813,1184 992,1184 1136,1130 1245,1023 1353,916 1407,772 1407,592 1407,412 1353,268 1245,161 1136,54 992,0 813,0 Z"/>
</g>
<g id="bullet-char-template-8226" transform="scale(0.00048828125,-0.00048828125)">
<path d="M 346,457 C 273,457 209,483 155,535 101,586 74,649 74,723 74,796 101,859 155,911 209,963 273,989 346,989 419,989 480,963 531,910 582,859 608,796 608,723 608,648 583,586 532,535 482,483 420,457 346,457 Z"/>
</g>
<g id="bullet-char-template-8211" transform="scale(0.00048828125,-0.00048828125)">
<path d="M -4,459 L 1135,459 1135,606 -4,606 -4,459 Z"/>
</g>
<g id="bullet-char-template-61548" transform="scale(0.00048828125,-0.00048828125)">
<path d="M 173,740 C 173,903 231,1043 346,1159 462,1274 601,1332 765,1332 928,1332 1067,1274 1183,1159 1299,1043 1357,903 1357,740 1357,577 1299,437 1183,322 1067,206 928,148 765,148 601,148 462,206 346,322 231,437 173,577 173,740 Z"/>
</g>
</defs>
<defs class="TextEmbeddedBitmaps"/>
<g>
<g id="id2" class="Master_Slide">
<g id="bg-id2" class="Background"/>
<g id="bo-id2" class="BackgroundObjects"/>
</g>
</g>
<g class="SlideGroup">
<g>
<g id="container-id1">
<g id="id1" class="Slide" clip-path="url(#presentation_clip_path)">
<g class="Page">
<g class="com.sun.star.drawing.ClosedBezierShape">
<g id="id3">
<rect class="BoundingBox" stroke="none" fill="none" x="6279" y="7479" width="39055" height="2155"/>
<path fill="rgb(0,0,0)" fill-opacity="0.251" stroke="rgb(255,255,255)" stroke-opacity="0.251" d="M 25806,9615 L 44998,9615 C 45173,9615 45315,9472 45315,9297 L 45315,7815 C 45315,7639 45173,7497 44998,7497 L 6615,7497 C 6439,7497 6297,7639 6297,7815 L 6297,9297 C 6297,9472 6439,9615 6615,9615 L 25806,9615 Z"/>
<defs>
<mask id="mask1">
<g>
<defs>
<linearGradient id="gradient1" x1="25806" y1="7480" x2="25806" y2="9633" gradientUnits="userSpaceOnUse">
<stop offset="0.5" style="stop-color:rgb(191,191,191)"/>
<stop offset="0.5" style="stop-color:rgb(191,191,191)"/>
<stop offset="1" style="stop-color:rgb(191,191,191)"/>
<stop offset="1" style="stop-color:rgb(191,191,191)"/>
</linearGradient>
</defs>
<path style="fill:url(#gradient1)" d="M 6280,7480 L 45333,7480 45333,9633 6280,9633 6280,7480 Z"/>
</g>
</mask>
</defs>
<g style="mask:url(#mask1)">
<path fill="none" stroke="rgb(0,0,0)" stroke-width="35" stroke-linejoin="miter" d="M 25806,9615 L 44998,9615 C 45173,9615 45315,9472 45315,9297 L 45315,7815 C 45315,7639 45173,7497 44998,7497 L 6615,7497 C 6439,7497 6297,7639 6297,7815 L 6297,9297 C 6297,9472 6439,9615 6615,9615 L 25806,9615 Z"/>
</g>
</g>
</g>
<g class="com.sun.star.drawing.ClosedBezierShape">
<g id="id4">
<rect class="BoundingBox" stroke="none" fill="none" x="6209" y="7373" width="39055" height="2155"/>
<g>
<defs>
<linearGradient id="gradient2" x1="25736" y1="7391" x2="25736" y2="9509" gradientUnits="userSpaceOnUse">
<stop offset="0" style="stop-color:rgb(213,232,212)"/>
<stop offset="1" style="stop-color:rgb(151,208,119)"/>
</linearGradient>
</defs>
<path style="fill:url(#gradient2)" d="M 25736,9509 L 44928,9509 44960,9507 44992,9503 45022,9495 45051,9484 45079,9470 45105,9455 45130,9436 45152,9416 45173,9393 45191,9369 45207,9342 45220,9315 45231,9285 45239,9255 45243,9223 45245,9191 45245,7709 45243,7676 45239,7645 45231,7614 45220,7585 45207,7557 45191,7531 45173,7507 45152,7484 45130,7463 45105,7445 45079,7429 45051,7416 45022,7405 44992,7397 44960,7393 44928,7391 6545,7391 6512,7393 6481,7397 6450,7405 6421,7416 6393,7429 6367,7445 6343,7463 6320,7484 6299,7507 6281,7531 6265,7557 6252,7585 6241,7614 6233,7645 6229,7676 6227,7709 6227,9191 6229,9223 6233,9255 6241,9285 6252,9315 6265,9342 6281,9369 6299,9393 6320,9416 6343,9436 6367,9455 6393,9470 6421,9484 6450,9495 6481,9503 6512,9507 6545,9509 25736,9509 Z"/>
</g>
<path fill="none" stroke="rgb(130,179,102)" stroke-width="35" stroke-linejoin="miter" d="M 25736,9509 L 44928,9509 C 45103,9509 45245,9366 45245,9191 L 45245,7709 C 45245,7533 45103,7391 44928,7391 L 6545,7391 C 6369,7391 6227,7533 6227,7709 L 6227,9191 C 6227,9366 6369,9509 6545,9509 L 25736,9509 Z"/>
</g>
</g>
<g class="com.sun.star.drawing.ClosedBezierShape">
<g id="id5">
<rect class="BoundingBox" stroke="none" fill="none" x="811" y="16651" width="4800" height="5964"/>
<path fill="rgb(0,0,0)" fill-opacity="0.251" stroke="rgb(255,255,255)" stroke-opacity="0.251" d="M 829,17869 C 829,16269 5592,16269 5592,17869 L 5592,21397 C 5592,22996 829,22996 829,21397 L 829,17869 Z"/>
<defs>
<mask id="mask2">
<g>
<defs>
<linearGradient id="gradient3" x1="3210" y1="16652" x2="3210" y2="22614" gradientUnits="userSpaceOnUse">
<stop offset="0.5" style="stop-color:rgb(191,191,191)"/>
<stop offset="0.5" style="stop-color:rgb(191,191,191)"/>
<stop offset="1" style="stop-color:rgb(191,191,191)"/>
<stop offset="1" style="stop-color:rgb(191,191,191)"/>
</linearGradient>
</defs>
<path style="fill:url(#gradient3)" d="M 812,16652 L 5609,16652 5609,22614 812,22614 812,16652 Z"/>
</g>
</mask>
</defs>
<g style="mask:url(#mask2)">
<path fill="none" stroke="rgb(0,0,0)" stroke-width="35" stroke-linejoin="miter" d="M 829,17869 C 829,16269 5592,16269 5592,17869 L 5592,21397 C 5592,22996 829,22996 829,21397 L 829,17869 Z"/>
</g>
</g>
</g>
<g class="com.sun.star.drawing.ClosedBezierShape">
<g id="id6">
<rect class="BoundingBox" stroke="none" fill="none" x="740" y="16545" width="4800" height="5964"/>
<g>
<defs>
<linearGradient id="gradient4" x1="3139" y1="16563" x2="3139" y2="22490" gradientUnits="userSpaceOnUse">
<stop offset="0" style="stop-color:rgb(219,250,252)"/>
<stop offset="1" style="stop-color:rgb(125,217,224)"/>
</linearGradient>
</defs>
<path style="fill:url(#gradient4)" d="M 758,17763 L 772,17618 811,17482 876,17355 963,17238 1071,17130 1198,17032 1342,16943 1502,16863 1863,16732 2265,16638 2695,16582 3140,16563 3584,16582 4014,16638 4416,16732 4777,16863 4937,16943 5081,17032 5208,17130 5316,17238 5403,17355 5468,17482 5507,17618 5521,17763 5521,21291 5507,21436 5468,21572 5403,21699 5316,21816 5208,21923 5081,22022 4937,22111 4777,22190 4416,22322 4014,22415 3584,22472 3140,22490 2695,22472 2265,22415 1863,22322 1502,22190 1342,22111 1198,22022 1071,21923 963,21816 876,21699 811,21572 772,21436 758,21291 758,17763 Z"/>
</g>
<path fill="none" stroke="rgb(108,142,191)" stroke-width="35" stroke-linejoin="miter" d="M 758,17763 C 758,16163 5521,16163 5521,17763 L 5521,21291 C 5521,22890 758,22890 758,21291 L 758,17763 Z"/>
</g>
</g>
<g class="com.sun.star.drawing.OpenBezierShape">
<g id="id7">
<rect class="BoundingBox" stroke="none" fill="none" x="740" y="17762" width="4800" height="920"/>
<path fill="none" stroke="rgb(108,142,191)" stroke-width="35" stroke-linejoin="miter" d="M 758,17762 C 758,18963 5521,18963 5521,17762"/>
</g>
</g>
<g class="com.sun.star.drawing.LineShape">
<g id="id8">
<rect class="BoundingBox" stroke="none" fill="none" x="5957" y="19473" width="4786" height="107"/>
<path fill="none" stroke="rgb(0,0,0)" stroke-width="106" stroke-linejoin="miter" d="M 5957,19526 L 10742,19526"/>
</g>
</g>
<g class="com.sun.star.drawing.PolyPolygonShape">
<g id="id9">
<rect class="BoundingBox" stroke="none" fill="none" x="5520" y="19282" width="492" height="491"/>
<path fill="rgb(0,0,0)" stroke="none" d="M 5639,19527 L 5957,19368 5957,19686 5639,19527 Z"/>
<path fill="none" stroke="rgb(0,0,0)" stroke-width="106" stroke-linejoin="miter" d="M 5639,19527 L 5957,19368 5957,19686 5639,19527 Z"/>
</g>
</g>
<g class="com.sun.star.drawing.ClosedBezierShape">
<g id="id10">
<rect class="BoundingBox" stroke="none" fill="none" x="23001" y="12241" width="5682" height="2155"/>
<path fill="rgb(0,0,0)" fill-opacity="0.251" stroke="rgb(255,255,255)" stroke-opacity="0.251" d="M 25842,14377 L 28347,14377 C 28522,14377 28664,14234 28664,14059 L 28664,12577 C 28664,12401 28522,12259 28347,12259 L 23337,12259 C 23161,12259 23019,12401 23019,12577 L 23019,14059 C 23019,14234 23161,14377 23337,14377 L 25842,14377 Z"/>
<defs>
<mask id="mask3">
<g>
<defs>
<linearGradient id="gradient5" x1="25842" y1="12242" x2="25842" y2="14395" gradientUnits="userSpaceOnUse">
<stop offset="0.5" style="stop-color:rgb(191,191,191)"/>
<stop offset="0.5" style="stop-color:rgb(191,191,191)"/>
<stop offset="1" style="stop-color:rgb(191,191,191)"/>
<stop offset="1" style="stop-color:rgb(191,191,191)"/>
</linearGradient>
</defs>
<path style="fill:url(#gradient5)" d="M 23002,12242 L 28682,12242 28682,14395 23002,14395 23002,12242 Z"/>
</g>
</mask>
</defs>
<g style="mask:url(#mask3)">
<path fill="none" stroke="rgb(0,0,0)" stroke-width="35" stroke-linejoin="miter" d="M 25842,14377 L 28347,14377 C 28522,14377 28664,14234 28664,14059 L 28664,12577 C 28664,12401 28522,12259 28347,12259 L 23337,12259 C 23161,12259 23019,12401 23019,12577 L 23019,14059 C 23019,14234 23161,14377 23337,14377 L 25842,14377 Z"/>
</g>
</g>
</g>
<g class="com.sun.star.drawing.ClosedBezierShape">
<g id="id11">
<rect class="BoundingBox" stroke="none" fill="none" x="22930" y="12135" width="5682" height="2155"/>
<g>
<defs>
<linearGradient id="gradient6" x1="25770" y1="12153" x2="25770" y2="14271" gradientUnits="userSpaceOnUse">
<stop offset="0" style="stop-color:rgb(219,250,252)"/>
<stop offset="1" style="stop-color:rgb(125,217,224)"/>
</linearGradient>
</defs>
<path style="fill:url(#gradient6)" d="M 25771,14271 L 28276,14271 28308,14269 28340,14265 28370,14257 28399,14246 28427,14232 28453,14217 28478,14198 28500,14178 28521,14155 28539,14131 28555,14104 28568,14077 28579,14047 28587,14017 28591,13985 28593,13953 28593,12471 28591,12438 28587,12407 28579,12376 28568,12347 28555,12319 28539,12293 28521,12269 28500,12246 28478,12225 28453,12207 28427,12191 28399,12178 28370,12167 28340,12159 28308,12155 28276,12153 23266,12153 23233,12155 23202,12159 23171,12167 23142,12178 23114,12191 23088,12207 23064,12225 23041,12246 23020,12269 23002,12293 22986,12319 22973,12347 22962,12376 22954,12407 22950,12438 22948,12471 22948,13953 22950,13985 22954,14017 22962,14047 22973,14077 22986,14104 23002,14131 23020,14155 23041,14178 23064,14198 23088,14217 23114,14232 23142,14246 23171,14257 23202,14265 23233,14269 23266,14271 25771,14271 Z"/>
</g>
<path fill="none" stroke="rgb(108,142,191)" stroke-width="35" stroke-linejoin="miter" d="M 25771,14271 L 28276,14271 C 28451,14271 28593,14128 28593,13953 L 28593,12471 C 28593,12295 28451,12153 28276,12153 L 23266,12153 C 23090,12153 22948,12295 22948,12471 L 22948,13953 C 22948,14128 23090,14271 23266,14271 L 25771,14271 Z"/>
</g>
</g>
<g class="com.sun.star.drawing.LineShape">
<g id="id12">
<rect class="BoundingBox" stroke="none" fill="none" x="25682" y="9506" width="138" height="2214"/>
<path fill="none" stroke="rgb(0,0,0)" stroke-width="106" stroke-linejoin="miter" d="M 25735,9507 L 25766,11718"/>
</g>
</g>
<g class="com.sun.star.drawing.PolyPolygonShape">
<g id="id13">
<rect class="BoundingBox" stroke="none" fill="none" x="25519" y="11660" width="491" height="496"/>
<path fill="rgb(0,0,0)" stroke="none" d="M 25769,12036 L 25606,11719 25924,11715 25769,12036 Z"/>
<path fill="none" stroke="rgb(0,0,0)" stroke-width="106" stroke-linejoin="miter" d="M 25769,12036 L 25606,11719 25924,11715 25769,12036 Z"/>
</g>
</g>
<g class="com.sun.star.drawing.LineShape">
<g id="id14">
<rect class="BoundingBox" stroke="none" fill="none" x="17591" y="14223" width="6232" height="3407"/>
<path fill="none" stroke="rgb(0,0,0)" stroke-width="106" stroke-linejoin="miter" d="M 23796,14270 L 17617,17582"/>
</g>
</g>
<g class="com.sun.star.drawing.PolyPolygonShape">
<g id="id15">
<rect class="BoundingBox" stroke="none" fill="none" x="17233" y="17340" width="550" height="449"/>
<path fill="rgb(0,0,0)" stroke="none" d="M 17338,17732 L 17543,17441 17694,17722 17338,17732 Z"/>
<path fill="none" stroke="rgb(0,0,0)" stroke-width="106" stroke-linejoin="miter" d="M 17338,17732 L 17543,17441 17694,17722 17338,17732 Z"/>
</g>
</g>
<g class="com.sun.star.drawing.LineShape">
<g id="id16">
<rect class="BoundingBox" stroke="none" fill="none" x="28097" y="14429" width="5819" height="3195"/>
<path fill="none" stroke="rgb(0,0,0)" stroke-width="106" stroke-linejoin="miter" d="M 28123,14476 L 33889,17576"/>
</g>
</g>
<g class="com.sun.star.drawing.PolyPolygonShape">
<g id="id17">
<rect class="BoundingBox" stroke="none" fill="none" x="27738" y="14269" width="550" height="450"/>
<path fill="rgb(0,0,0)" stroke="none" d="M 27843,14326 L 28199,14337 28048,14617 27843,14326 Z"/>
<path fill="none" stroke="rgb(0,0,0)" stroke-width="106" stroke-linejoin="miter" d="M 27843,14326 L 28199,14337 28048,14617 27843,14326 Z"/>
</g>
</g>
<g class="com.sun.star.drawing.PolyPolygonShape">
<g id="id18">
<rect class="BoundingBox" stroke="none" fill="none" x="33725" y="17334" width="550" height="449"/>
<path fill="rgb(0,0,0)" stroke="none" d="M 34169,17726 L 33813,17716 33964,17435 34169,17726 Z"/>
<path fill="none" stroke="rgb(0,0,0)" stroke-width="106" stroke-linejoin="miter" d="M 34169,17726 L 33813,17716 33964,17435 34169,17726 Z"/>
</g>
</g>
<g class="com.sun.star.drawing.LineShape">
<g id="id19">
<rect class="BoundingBox" stroke="none" fill="none" x="25717" y="14706" width="107" height="2093"/>
<path fill="none" stroke="rgb(0,0,0)" stroke-width="106" stroke-linejoin="miter" d="M 25770,14706 L 25770,16798"/>
</g>
</g>
<g class="com.sun.star.drawing.PolyPolygonShape">
<g id="id20">
<rect class="BoundingBox" stroke="none" fill="none" x="25526" y="14269" width="491" height="492"/>
<path fill="rgb(0,0,0)" stroke="none" d="M 25771,14388 L 25930,14706 25612,14706 25771,14388 Z"/>
<path fill="none" stroke="rgb(0,0,0)" stroke-width="106" stroke-linejoin="miter" d="M 25771,14388 L 25930,14706 25612,14706 25771,14388 Z"/>
</g>
</g>
<g class="com.sun.star.drawing.PolyPolygonShape">
<g id="id21">
<rect class="BoundingBox" stroke="none" fill="none" x="25526" y="16745" width="491" height="491"/>
<path fill="rgb(0,0,0)" stroke="none" d="M 25771,17116 L 25612,16798 25930,16798 25771,17116 Z"/>
<path fill="none" stroke="rgb(0,0,0)" stroke-width="106" stroke-linejoin="miter" d="M 25771,17116 L 25612,16798 25930,16798 25771,17116 Z"/>
</g>
</g>
<g class="com.sun.star.drawing.PolyLineShape">
<g id="id22">
<rect class="BoundingBox" stroke="none" fill="none" x="26658" y="16898" width="37" height="37"/>
</g>
</g>
<g class="com.sun.star.drawing.PolyPolygonShape">
<g id="id23">
<rect class="BoundingBox" stroke="none" fill="none" x="26676" y="16916" width="1" height="1"/>
<path fill="rgb(0,0,0)" stroke="none" d="M 26676,16916 L 26676,16916 Z"/>
</g>
</g>
<g class="com.sun.star.drawing.PolyPolygonShape">
<g id="id24">
<rect class="BoundingBox" stroke="none" fill="none" x="26676" y="16916" width="1" height="1"/>
<path fill="rgb(0,0,0)" stroke="none" d="M 26676,16916 L 26676,16916 Z"/>
</g>
</g>
<g class="com.sun.star.drawing.ClosedBezierShape">
<g id="id25">
<rect class="BoundingBox" stroke="none" fill="none" x="70" y="105" width="6529" height="4624"/>
<path fill="rgb(0,0,0)" fill-opacity="0.251" stroke="rgb(255,255,255)" stroke-opacity="0.251" d="M 3334,4710 L 5892,4710 C 6272,4710 6580,4402 6580,4022 L 6580,811 C 6580,431 6272,123 5892,123 L 776,123 C 396,123 88,431 88,811 L 88,4022 C 88,4402 396,4710 776,4710 L 3334,4710 Z"/>
<defs>
<mask id="mask4">
<g>
<defs>
<linearGradient id="gradient7" x1="3334" y1="106" x2="3334" y2="4728" gradientUnits="userSpaceOnUse">
<stop offset="0.5" style="stop-color:rgb(191,191,191)"/>
<stop offset="0.5" style="stop-color:rgb(191,191,191)"/>
<stop offset="1" style="stop-color:rgb(191,191,191)"/>
<stop offset="1" style="stop-color:rgb(191,191,191)"/>
</linearGradient>
</defs>
<path style="fill:url(#gradient7)" d="M 71,106 L 6598,106 6598,4728 71,4728 71,106 Z"/>
</g>
</mask>
</defs>
<g style="mask:url(#mask4)">
<path fill="none" stroke="rgb(0,0,0)" stroke-width="35" stroke-linejoin="miter" d="M 3334,4710 L 5892,4710 C 6272,4710 6580,4402 6580,4022 L 6580,811 C 6580,431 6272,123 5892,123 L 776,123 C 396,123 88,431 88,811 L 88,4022 C 88,4402 396,4710 776,4710 L 3334,4710 Z"/>
</g>
</g>
</g>
<g class="com.sun.star.drawing.ClosedBezierShape">
<g id="id26">
<rect class="BoundingBox" stroke="none" fill="none" x="0" y="0" width="6529" height="4624"/>
<g>
<defs>
<linearGradient id="gradient8" x1="3264" y1="18" x2="3264" y2="4605" gradientUnits="userSpaceOnUse">
<stop offset="0" style="stop-color:rgb(219,250,252)"/>
<stop offset="1" style="stop-color:rgb(125,217,224)"/>
</linearGradient>
</defs>
<path style="fill:url(#gradient8)" d="M 3264,4605 L 5822,4605 5892,4601 5961,4591 6027,4574 6090,4551 6150,4522 6207,4488 6260,4448 6309,4404 6353,4355 6393,4302 6427,4245 6456,4185 6479,4122 6496,4056 6506,3987 6510,3917 6510,706 6506,636 6496,567 6479,501 6456,438 6427,378 6393,321 6353,268 6309,220 6260,175 6207,135 6150,101 6090,72 6027,49 5961,32 5892,22 5822,18 706,18 636,22 567,32 501,49 438,72 378,101 321,135 268,175 220,220 175,268 135,321 101,378 72,438 49,501 32,567 22,636 18,706 18,3917 22,3987 32,4056 49,4122 72,4185 101,4245 135,4302 175,4355 220,4404 268,4448 321,4488 378,4522 438,4551 501,4574 567,4591 636,4601 706,4605 3264,4605 Z"/>
</g>
<path fill="none" stroke="rgb(108,142,191)" stroke-width="35" stroke-linejoin="miter" d="M 3264,4605 L 5822,4605 C 6202,4605 6510,4297 6510,3917 L 6510,706 C 6510,326 6202,18 5822,18 L 706,18 C 326,18 18,326 18,706 L 18,3917 C 18,4297 326,4605 706,4605 L 3264,4605 Z"/>
</g>
</g>
<g class="com.sun.star.drawing.ClosedBezierShape">
<g id="id27">
<rect class="BoundingBox" stroke="none" fill="none" x="811" y="2081" width="5047" height="2331"/>
<path fill="rgb(0,0,0)" fill-opacity="0.251" stroke="rgb(255,255,255)" stroke-opacity="0.251" d="M 3334,4393 L 5495,4393 C 5685,4393 5839,4239 5839,4049 L 5839,2443 C 5839,2253 5685,2099 5495,2099 L 1173,2099 C 983,2099 829,2253 829,2443 L 829,4049 C 829,4239 983,4393 1173,4393 L 3334,4393 Z"/>
<defs>
<mask id="mask5">
<g>
<defs>
<linearGradient id="gradient9" x1="3334" y1="2082" x2="3334" y2="4411" gradientUnits="userSpaceOnUse">
<stop offset="0.5" style="stop-color:rgb(191,191,191)"/>
<stop offset="0.5" style="stop-color:rgb(191,191,191)"/>
<stop offset="1" style="stop-color:rgb(191,191,191)"/>
<stop offset="1" style="stop-color:rgb(191,191,191)"/>
</linearGradient>
</defs>
<path style="fill:url(#gradient9)" d="M 812,2082 L 5857,2082 5857,4411 812,4411 812,2082 Z"/>
</g>
</mask>
</defs>
<g style="mask:url(#mask5)">
<path fill="none" stroke="rgb(0,0,0)" stroke-width="35" stroke-linejoin="miter" d="M 3334,4393 L 5495,4393 C 5685,4393 5839,4239 5839,4049 L 5839,2443 C 5839,2253 5685,2099 5495,2099 L 1173,2099 C 983,2099 829,2253 829,2443 L 829,4049 C 829,4239 983,4393 1173,4393 L 3334,4393 Z"/>
</g>
</g>
</g>
<g class="com.sun.star.drawing.ClosedBezierShape">
<g id="id28">
<rect class="BoundingBox" stroke="none" fill="none" x="740" y="1975" width="5047" height="2331"/>
<g>
<defs>
<linearGradient id="gradient10" x1="3263" y1="1993" x2="3263" y2="4287" gradientUnits="userSpaceOnUse">
<stop offset="0" style="stop-color:rgb(213,232,212)"/>
<stop offset="1" style="stop-color:rgb(151,208,119)"/>
</linearGradient>
</defs>
<path style="fill:url(#gradient10)" d="M 3263,4287 L 5424,4287 5459,4285 5493,4280 5526,4272 5558,4260 5588,4245 5616,4228 5643,4208 5667,4186 5689,4162 5709,4135 5726,4107 5741,4077 5753,4045 5761,4012 5766,3978 5768,3943 5768,2337 5766,2302 5761,2268 5753,2235 5741,2203 5726,2173 5709,2145 5689,2118 5667,2094 5643,2072 5616,2052 5588,2035 5558,2020 5526,2008 5493,2000 5459,1995 5424,1993 1102,1993 1067,1995 1033,2000 1000,2008 968,2020 938,2035 910,2052 883,2072 859,2094 837,2118 817,2145 800,2173 785,2203 773,2235 765,2268 760,2302 758,2337 758,3943 760,3978 765,4012 773,4045 785,4077 800,4107 817,4135 837,4162 859,4186 883,4208 910,4228 938,4245 968,4260 1000,4272 1033,4280 1067,4285 1102,4287 3263,4287 Z"/>
</g>
<path fill="none" stroke="rgb(130,179,102)" stroke-width="35" stroke-linejoin="miter" d="M 3263,4287 L 5424,4287 C 5614,4287 5768,4133 5768,3943 L 5768,2337 C 5768,2147 5614,1993 5424,1993 L 1102,1993 C 912,1993 758,2147 758,2337 L 758,3943 C 758,4133 912,4287 1102,4287 L 3263,4287 Z"/>
</g>
</g>
<g class="com.sun.star.drawing.ClosedBezierShape">
<g id="id29">
<rect class="BoundingBox" stroke="none" fill="none" x="22577" y="105" width="6529" height="4624"/>
<path fill="rgb(0,0,0)" fill-opacity="0.251" stroke="rgb(255,255,255)" stroke-opacity="0.251" d="M 25841,4710 L 28399,4710 C 28779,4710 29087,4402 29087,4022 L 29087,811 C 29087,431 28779,123 28399,123 L 23283,123 C 22903,123 22595,431 22595,811 L 22595,4022 C 22595,4402 22903,4710 23283,4710 L 25841,4710 Z"/>
<defs>
<mask id="mask6">
<g>
<defs>
<linearGradient id="gradient11" x1="25841" y1="106" x2="25841" y2="4728" gradientUnits="userSpaceOnUse">
<stop offset="0.5" style="stop-color:rgb(191,191,191)"/>
<stop offset="0.5" style="stop-color:rgb(191,191,191)"/>
<stop offset="1" style="stop-color:rgb(191,191,191)"/>
<stop offset="1" style="stop-color:rgb(191,191,191)"/>
</linearGradient>
</defs>
<path style="fill:url(#gradient11)" d="M 22578,106 L 29105,106 29105,4728 22578,4728 22578,106 Z"/>
</g>
</mask>
</defs>
<g style="mask:url(#mask6)">
<path fill="none" stroke="rgb(0,0,0)" stroke-width="35" stroke-linejoin="miter" d="M 25841,4710 L 28399,4710 C 28779,4710 29087,4402 29087,4022 L 29087,811 C 29087,431 28779,123 28399,123 L 23283,123 C 22903,123 22595,431 22595,811 L 22595,4022 C 22595,4402 22903,4710 23283,4710 L 25841,4710 Z"/>
</g>
</g>
</g>
<g class="com.sun.star.drawing.ClosedBezierShape">
<g id="id30">
<rect class="BoundingBox" stroke="none" fill="none" x="22507" y="0" width="6529" height="4624"/>
<g>
<defs>
<linearGradient id="gradient12" x1="25771" y1="18" x2="25771" y2="4605" gradientUnits="userSpaceOnUse">
<stop offset="0" style="stop-color:rgb(219,250,252)"/>
<stop offset="1" style="stop-color:rgb(125,217,224)"/>
</linearGradient>
</defs>
<path style="fill:url(#gradient12)" d="M 25771,4605 L 28329,4605 28399,4601 28468,4591 28534,4574 28597,4551 28657,4522 28714,4488 28767,4448 28816,4404 28860,4355 28900,4302 28934,4245 28963,4185 28986,4122 29003,4056 29013,3987 29017,3917 29017,706 29013,636 29003,567 28986,501 28963,438 28934,378 28900,321 28860,268 28816,220 28767,175 28714,135 28657,101 28597,72 28534,49 28468,32 28399,22 28329,18 23213,18 23143,22 23074,32 23008,49 22945,72 22885,101 22828,135 22775,175 22727,220 22682,268 22642,321 22608,378 22579,438 22556,501 22539,567 22529,636 22525,706 22525,3917 22529,3987 22539,4056 22556,4122 22579,4185 22608,4245 22642,4302 22682,4355 22727,4404 22775,4448 22828,4488 22885,4522 22945,4551 23008,4574 23074,4591 23143,4601 23213,4605 25771,4605 Z"/>
</g>
<path fill="none" stroke="rgb(108,142,191)" stroke-width="35" stroke-linejoin="miter" d="M 25771,4605 L 28329,4605 C 28709,4605 29017,4297 29017,3917 L 29017,706 C 29017,326 28709,18 28329,18 L 23213,18 C 22833,18 22525,326 22525,706 L 22525,3917 C 22525,4297 22833,4605 23213,4605 L 25771,4605 Z"/>
</g>
</g>
<g class="com.sun.star.drawing.ClosedBezierShape">
<g id="id31">
<rect class="BoundingBox" stroke="none" fill="none" x="23318" y="2081" width="5047" height="2331"/>
<path fill="rgb(0,0,0)" fill-opacity="0.251" stroke="rgb(255,255,255)" stroke-opacity="0.251" d="M 25841,4393 L 28002,4393 C 28192,4393 28346,4239 28346,4049 L 28346,2443 C 28346,2253 28192,2099 28002,2099 L 23680,2099 C 23490,2099 23336,2253 23336,2443 L 23336,4049 C 23336,4239 23490,4393 23680,4393 L 25841,4393 Z"/>
<defs>
<mask id="mask7">
<g>
<defs>
<linearGradient id="gradient13" x1="25841" y1="2082" x2="25841" y2="4411" gradientUnits="userSpaceOnUse">
<stop offset="0.5" style="stop-color:rgb(191,191,191)"/>
<stop offset="0.5" style="stop-color:rgb(191,191,191)"/>
<stop offset="1" style="stop-color:rgb(191,191,191)"/>
<stop offset="1" style="stop-color:rgb(191,191,191)"/>
</linearGradient>
</defs>
<path style="fill:url(#gradient13)" d="M 23319,2082 L 28364,2082 28364,4411 23319,4411 23319,2082 Z"/>
</g>
</mask>
</defs>
<g style="mask:url(#mask7)">
<path fill="none" stroke="rgb(0,0,0)" stroke-width="35" stroke-linejoin="miter" d="M 25841,4393 L 28002,4393 C 28192,4393 28346,4239 28346,4049 L 28346,2443 C 28346,2253 28192,2099 28002,2099 L 23680,2099 C 23490,2099 23336,2253 23336,2443 L 23336,4049 C 23336,4239 23490,4393 23680,4393 L 25841,4393 Z"/>
</g>
</g>
</g>
<g class="com.sun.star.drawing.ClosedBezierShape">
<g id="id32">
<rect class="BoundingBox" stroke="none" fill="none" x="23292" y="1975" width="5047" height="2331"/>
<g>
<defs>
<linearGradient id="gradient14" x1="25815" y1="1993" x2="25815" y2="4287" gradientUnits="userSpaceOnUse">
<stop offset="0" style="stop-color:rgb(213,232,212)"/>
<stop offset="1" style="stop-color:rgb(151,208,119)"/>
</linearGradient>
</defs>
<path style="fill:url(#gradient14)" d="M 25815,4287 L 27976,4287 28011,4285 28045,4280 28078,4272 28110,4260 28140,4245 28168,4228 28195,4208 28219,4186 28241,4162 28261,4135 28278,4107 28293,4077 28305,4045 28313,4012 28318,3978 28320,3943 28320,2337 28318,2302 28313,2268 28305,2235 28293,2203 28278,2173 28261,2145 28241,2118 28219,2094 28195,2072 28168,2052 28140,2035 28110,2020 28078,2008 28045,2000 28011,1995 27976,1993 23654,1993 23619,1995 23585,2000 23552,2008 23520,2020 23490,2035 23462,2052 23435,2072 23411,2094 23389,2118 23369,2145 23352,2173 23337,2203 23325,2235 23317,2268 23312,2302 23310,2337 23310,3943 23312,3978 23317,4012 23325,4045 23337,4077 23352,4107 23369,4135 23389,4162 23411,4186 23435,4208 23462,4228 23490,4245 23520,4260 23552,4272 23585,4280 23619,4285 23654,4287 25815,4287 Z"/>
</g>
<path fill="none" stroke="rgb(130,179,102)" stroke-width="35" stroke-linejoin="miter" d="M 25815,4287 L 27976,4287 C 28166,4287 28320,4133 28320,3943 L 28320,2337 C 28320,2147 28166,1993 27976,1993 L 23654,1993 C 23464,1993 23310,2147 23310,2337 L 23310,3943 C 23310,4133 23464,4287 23654,4287 L 25815,4287 Z"/>
</g>
</g>
<g class="com.sun.star.drawing.LineShape">
<g id="id33">
<rect class="BoundingBox" stroke="none" fill="none" x="3108" y="5038" width="191" height="11527"/>
<path fill="none" stroke="rgb(0,0,0)" stroke-width="106" stroke-linejoin="miter" d="M 3245,5039 L 3161,16563"/>
</g>
</g>
<g class="com.sun.star.drawing.PolyPolygonShape">
<g id="id34">
<rect class="BoundingBox" stroke="none" fill="none" x="2999" y="4603" width="491" height="494"/>
<path fill="rgb(0,0,0)" stroke="none" d="M 3246,4722 L 3403,5042 3085,5039 3246,4722 Z"/>
<path fill="none" stroke="rgb(0,0,0)" stroke-width="106" stroke-linejoin="miter" d="M 3246,4722 L 3403,5042 3085,5039 3246,4722 Z"/>
</g>
</g>
<g class="com.sun.star.drawing.LineShape">
<g id="id35">
<rect class="BoundingBox" stroke="none" fill="none" x="25691" y="4603" width="122" height="2355"/>
<path fill="none" stroke="rgb(0,0,0)" stroke-width="106" stroke-linejoin="miter" d="M 25759,4604 L 25744,6956"/>
</g>
</g>
<g class="com.sun.star.drawing.PolyPolygonShape">
<g id="id36">
<rect class="BoundingBox" stroke="none" fill="none" x="25499" y="6900" width="491" height="494"/>
<path fill="rgb(0,0,0)" stroke="none" d="M 25742,7274 L 25585,6954 25903,6956 25742,7274 Z"/>
<path fill="none" stroke="rgb(0,0,0)" stroke-width="106" stroke-linejoin="miter" d="M 25742,7274 L 25585,6954 25903,6956 25742,7274 Z"/>
</g>
</g>
<g class="com.sun.star.drawing.LineShape">
<g id="id37">
<rect class="BoundingBox" stroke="none" fill="none" x="3835" y="9685" width="11784" height="7102"/>
<path fill="none" stroke="rgb(0,0,0)" stroke-width="106" stroke-linejoin="miter" d="M 15590,9731 L 15317,9894"/>
<path fill="none" stroke="rgb(0,0,0)" stroke-width="106" stroke-linejoin="miter" d="M 15044,10057 L 14771,10220"/>
<path fill="none" stroke="rgb(0,0,0)" stroke-width="106" stroke-linejoin="miter" d="M 14498,10384 L 14225,10547"/>
<path fill="none" stroke="rgb(0,0,0)" stroke-width="106" stroke-linejoin="miter" d="M 13952,10710 L 13679,10873"/>
<path fill="none" stroke="rgb(0,0,0)" stroke-width="106" stroke-linejoin="miter" d="M 13406,11036 L 13133,11199"/>
<path fill="none" stroke="rgb(0,0,0)" stroke-width="106" stroke-linejoin="miter" d="M 12860,11362 L 12587,11526"/>
<path fill="none" stroke="rgb(0,0,0)" stroke-width="106" stroke-linejoin="miter" d="M 12314,11689 L 12041,11852"/>
<path fill="none" stroke="rgb(0,0,0)" stroke-width="106" stroke-linejoin="miter" d="M 11769,12015 L 11496,12178"/>
<path fill="none" stroke="rgb(0,0,0)" stroke-width="106" stroke-linejoin="miter" d="M 11223,12341 L 10950,12504"/>
<path fill="none" stroke="rgb(0,0,0)" stroke-width="106" stroke-linejoin="miter" d="M 10677,12668 L 10404,12831"/>
<path fill="none" stroke="rgb(0,0,0)" stroke-width="106" stroke-linejoin="miter" d="M 10131,12994 L 9858,13157"/>
<path fill="none" stroke="rgb(0,0,0)" stroke-width="106" stroke-linejoin="miter" d="M 9585,13320 L 9312,13483"/>
<path fill="none" stroke="rgb(0,0,0)" stroke-width="106" stroke-linejoin="miter" d="M 9039,13646 L 8766,13810"/>
<path fill="none" stroke="rgb(0,0,0)" stroke-width="106" stroke-linejoin="miter" d="M 8493,13973 L 8220,14136"/>
<path fill="none" stroke="rgb(0,0,0)" stroke-width="106" stroke-linejoin="miter" d="M 7947,14299 L 7674,14462"/>
<path fill="none" stroke="rgb(0,0,0)" stroke-width="106" stroke-linejoin="miter" d="M 7401,14625 L 7128,14788"/>
<path fill="none" stroke="rgb(0,0,0)" stroke-width="106" stroke-linejoin="miter" d="M 6855,14952 L 6582,15115"/>
<path fill="none" stroke="rgb(0,0,0)" stroke-width="106" stroke-linejoin="miter" d="M 6309,15278 L 6036,15441"/>
<path fill="none" stroke="rgb(0,0,0)" stroke-width="106" stroke-linejoin="miter" d="M 5763,15604 L 5490,15767"/>
<path fill="none" stroke="rgb(0,0,0)" stroke-width="106" stroke-linejoin="miter" d="M 5217,15930 L 4944,16094"/>
<path fill="none" stroke="rgb(0,0,0)" stroke-width="106" stroke-linejoin="miter" d="M 4672,16257 L 4399,16420"/>
<path fill="none" stroke="rgb(0,0,0)" stroke-width="106" stroke-linejoin="miter" d="M 4126,16583 L 3863,16740"/>
</g>
</g>
<g class="com.sun.star.drawing.PolyPolygonShape">
<g id="id38">
<rect class="BoundingBox" stroke="none" fill="none" x="15418" y="9507" width="548" height="463"/>
<path fill="rgb(0,0,0)" stroke="none" d="M 15863,9568 L 15671,9868 15508,9595 15863,9568 Z"/>
<path fill="none" stroke="rgb(0,0,0)" stroke-width="106" stroke-linejoin="miter" d="M 15863,9568 L 15671,9868 15508,9595 15863,9568 Z"/>
</g>
</g>
<g class="com.sun.star.drawing.ClosedBezierShape">
<g id="id39">
<rect class="BoundingBox" stroke="none" fill="none" x="10795" y="17321" width="6529" height="4624"/>
<path fill="rgb(0,0,0)" fill-opacity="0.251" stroke="rgb(255,255,255)" stroke-opacity="0.251" d="M 14059,21926 L 16617,21926 C 16997,21926 17305,21618 17305,21238 L 17305,18027 C 17305,17647 16997,17339 16617,17339 L 11501,17339 C 11121,17339 10813,17647 10813,18027 L 10813,21238 C 10813,21618 11121,21926 11501,21926 L 14059,21926 Z"/>
<defs>
<mask id="mask8">
<g>
<defs>
<linearGradient id="gradient15" x1="14059" y1="17322" x2="14059" y2="21944" gradientUnits="userSpaceOnUse">
<stop offset="0.5" style="stop-color:rgb(191,191,191)"/>
<stop offset="0.5" style="stop-color:rgb(191,191,191)"/>
<stop offset="1" style="stop-color:rgb(191,191,191)"/>
<stop offset="1" style="stop-color:rgb(191,191,191)"/>
</linearGradient>
</defs>
<path style="fill:url(#gradient15)" d="M 10796,17322 L 17323,17322 17323,21944 10796,21944 10796,17322 Z"/>
</g>
</mask>
</defs>
<g style="mask:url(#mask8)">
<path fill="none" stroke="rgb(0,0,0)" stroke-width="35" stroke-linejoin="miter" d="M 14059,21926 L 16617,21926 C 16997,21926 17305,21618 17305,21238 L 17305,18027 C 17305,17647 16997,17339 16617,17339 L 11501,17339 C 11121,17339 10813,17647 10813,18027 L 10813,21238 C 10813,21618 11121,21926 11501,21926 L 14059,21926 Z"/>
</g>
</g>
</g>
<g class="com.sun.star.drawing.ClosedBezierShape">
<g id="id40">
<rect class="BoundingBox" stroke="none" fill="none" x="10724" y="17215" width="6529" height="4624"/>
<g>
<defs>
<linearGradient id="gradient16" x1="13988" y1="17233" x2="13988" y2="21820" gradientUnits="userSpaceOnUse">
<stop offset="0" style="stop-color:rgb(219,250,252)"/>
<stop offset="1" style="stop-color:rgb(125,217,224)"/>
</linearGradient>
</defs>
<path style="fill:url(#gradient16)" d="M 13988,21820 L 16546,21820 16616,21816 16685,21806 16751,21789 16814,21766 16874,21737 16931,21703 16984,21663 17033,21619 17077,21570 17117,21517 17151,21460 17180,21400 17203,21337 17220,21271 17230,21202 17234,21132 17234,17921 17230,17851 17220,17782 17203,17716 17180,17653 17151,17593 17117,17536 17077,17483 17033,17435 16984,17390 16931,17350 16874,17316 16814,17287 16751,17264 16685,17247 16616,17237 16546,17233 11430,17233 11360,17237 11291,17247 11225,17264 11162,17287 11102,17316 11045,17350 10992,17390 10944,17435 10899,17483 10859,17536 10825,17593 10796,17653 10773,17716 10756,17782 10746,17851 10742,17921 10742,21132 10746,21202 10756,21271 10773,21337 10796,21400 10825,21460 10859,21517 10899,21570 10944,21619 10992,21663 11045,21703 11102,21737 11162,21766 11225,21789 11291,21806 11360,21816 11430,21820 13988,21820 Z"/>
</g>
<path fill="none" stroke="rgb(108,142,191)" stroke-width="35" stroke-linejoin="miter" d="M 13988,21820 L 16546,21820 C 16926,21820 17234,21512 17234,21132 L 17234,17921 C 17234,17541 16926,17233 16546,17233 L 11430,17233 C 11050,17233 10742,17541 10742,17921 L 10742,21132 C 10742,21512 11050,21820 11430,21820 L 13988,21820 Z"/>
</g>
</g>
<g class="com.sun.star.drawing.ClosedBezierShape">
<g id="id41">
<rect class="BoundingBox" stroke="none" fill="none" x="11535" y="19297" width="5047" height="2331"/>
<path fill="rgb(0,0,0)" fill-opacity="0.251" stroke="rgb(255,255,255)" stroke-opacity="0.251" d="M 14058,21609 L 16219,21609 C 16409,21609 16563,21455 16563,21265 L 16563,19659 C 16563,19469 16409,19315 16219,19315 L 11897,19315 C 11707,19315 11553,19469 11553,19659 L 11553,21265 C 11553,21455 11707,21609 11897,21609 L 14058,21609 Z"/>
<defs>
<mask id="mask9">
<g>
<defs>
<linearGradient id="gradient17" x1="14058" y1="19298" x2="14058" y2="21627" gradientUnits="userSpaceOnUse">
<stop offset="0.5" style="stop-color:rgb(191,191,191)"/>
<stop offset="0.5" style="stop-color:rgb(191,191,191)"/>
<stop offset="1" style="stop-color:rgb(191,191,191)"/>
<stop offset="1" style="stop-color:rgb(191,191,191)"/>
</linearGradient>
</defs>
<path style="fill:url(#gradient17)" d="M 11535,19298 L 16581,19298 16581,21627 11535,21627 11535,19298 Z"/>
</g>
</mask>
</defs>
<g style="mask:url(#mask9)">
<path fill="none" stroke="rgb(0,0,0)" stroke-width="35" stroke-linejoin="miter" d="M 14058,21609 L 16219,21609 C 16409,21609 16563,21455 16563,21265 L 16563,19659 C 16563,19469 16409,19315 16219,19315 L 11897,19315 C 11707,19315 11553,19469 11553,19659 L 11553,21265 C 11553,21455 11707,21609 11897,21609 L 14058,21609 Z"/>
</g>
</g>
</g>
<g class="com.sun.star.drawing.ClosedBezierShape">
<g id="id42">
<rect class="BoundingBox" stroke="none" fill="none" x="11465" y="19191" width="5047" height="2331"/>
<g>
<defs>
<linearGradient id="gradient18" x1="13988" y1="19209" x2="13988" y2="21503" gradientUnits="userSpaceOnUse">
<stop offset="0" style="stop-color:rgb(213,232,212)"/>
<stop offset="1" style="stop-color:rgb(151,208,119)"/>
</linearGradient>
</defs>
<path style="fill:url(#gradient18)" d="M 13988,21503 L 16149,21503 16184,21501 16218,21496 16251,21488 16283,21476 16313,21461 16341,21444 16368,21424 16392,21402 16414,21378 16434,21351 16451,21323 16466,21293 16478,21261 16486,21228 16491,21194 16493,21159 16493,19553 16491,19518 16486,19484 16478,19451 16466,19419 16451,19389 16434,19361 16414,19334 16392,19310 16368,19288 16341,19268 16313,19251 16283,19236 16251,19224 16218,19216 16184,19211 16149,19209 11827,19209 11792,19211 11758,19216 11725,19224 11693,19236 11663,19251 11635,19268 11608,19288 11584,19310 11562,19334 11542,19361 11525,19389 11510,19419 11498,19451 11490,19484 11485,19518 11483,19553 11483,21159 11485,21194 11490,21228 11498,21261 11510,21293 11525,21323 11542,21351 11562,21378 11584,21402 11608,21424 11635,21444 11663,21461 11693,21476 11725,21488 11758,21496 11792,21501 11827,21503 13988,21503 Z"/>
</g>
<path fill="none" stroke="rgb(130,179,102)" stroke-width="35" stroke-linejoin="miter" d="M 13988,21503 L 16149,21503 C 16339,21503 16493,21349 16493,21159 L 16493,19553 C 16493,19363 16339,19209 16149,19209 L 11827,19209 C 11637,19209 11483,19363 11483,19553 L 11483,21159 C 11483,21349 11637,21503 11827,21503 L 13988,21503 Z"/>
</g>
</g>
<g class="com.sun.star.drawing.ClosedBezierShape">
<g id="id43">
<rect class="BoundingBox" stroke="none" fill="none" x="34325" y="17321" width="6529" height="4624"/>
<path fill="rgb(0,0,0)" fill-opacity="0.251" stroke="rgb(255,255,255)" stroke-opacity="0.251" d="M 37589,21926 L 40147,21926 C 40527,21926 40835,21618 40835,21238 L 40835,18027 C 40835,17647 40527,17339 40147,17339 L 35031,17339 C 34651,17339 34343,17647 34343,18027 L 34343,21238 C 34343,21618 34651,21926 35031,21926 L 37589,21926 Z"/>
<defs>
<mask id="mask10">
<g>
<defs>
<linearGradient id="gradient19" x1="37589" y1="17322" x2="37589" y2="21944" gradientUnits="userSpaceOnUse">
<stop offset="0.5" style="stop-color:rgb(191,191,191)"/>
<stop offset="0.5" style="stop-color:rgb(191,191,191)"/>
<stop offset="1" style="stop-color:rgb(191,191,191)"/>
<stop offset="1" style="stop-color:rgb(191,191,191)"/>
</linearGradient>
</defs>
<path style="fill:url(#gradient19)" d="M 34326,17322 L 40853,17322 40853,21944 34326,21944 34326,17322 Z"/>
</g>
</mask>
</defs>
<g style="mask:url(#mask10)">
<path fill="none" stroke="rgb(0,0,0)" stroke-width="35" stroke-linejoin="miter" d="M 37589,21926 L 40147,21926 C 40527,21926 40835,21618 40835,21238 L 40835,18027 C 40835,17647 40527,17339 40147,17339 L 35031,17339 C 34651,17339 34343,17647 34343,18027 L 34343,21238 C 34343,21618 34651,21926 35031,21926 L 37589,21926 Z"/>
</g>
</g>
</g>
<g class="com.sun.star.drawing.ClosedBezierShape">
<g id="id44">
<rect class="BoundingBox" stroke="none" fill="none" x="34254" y="17215" width="6529" height="4624"/>
<g>
<defs>
<linearGradient id="gradient20" x1="37518" y1="17233" x2="37518" y2="21820" gradientUnits="userSpaceOnUse">
<stop offset="0" style="stop-color:rgb(219,250,252)"/>
<stop offset="1" style="stop-color:rgb(125,217,224)"/>
</linearGradient>
</defs>
<path style="fill:url(#gradient20)" d="M 37518,21820 L 40076,21820 40146,21816 40215,21806 40281,21789 40344,21766 40404,21737 40461,21703 40514,21663 40563,21619 40607,21570 40647,21517 40681,21460 40710,21400 40733,21337 40750,21271 40760,21202 40764,21132 40764,17921 40760,17851 40750,17782 40733,17716 40710,17653 40681,17593 40647,17536 40607,17483 40563,17435 40514,17390 40461,17350 40404,17316 40344,17287 40281,17264 40215,17247 40146,17237 40076,17233 34960,17233 34890,17237 34821,17247 34755,17264 34692,17287 34632,17316 34575,17350 34522,17390 34474,17435 34429,17483 34389,17536 34355,17593 34326,17653 34303,17716 34286,17782 34276,17851 34272,17921 34272,21132 34276,21202 34286,21271 34303,21337 34326,21400 34355,21460 34389,21517 34429,21570 34474,21619 34522,21663 34575,21703 34632,21737 34692,21766 34755,21789 34821,21806 34890,21816 34960,21820 37518,21820 Z"/>
</g>
<path fill="none" stroke="rgb(108,142,191)" stroke-width="35" stroke-linejoin="miter" d="M 37518,21820 L 40076,21820 C 40456,21820 40764,21512 40764,21132 L 40764,17921 C 40764,17541 40456,17233 40076,17233 L 34960,17233 C 34580,17233 34272,17541 34272,17921 L 34272,21132 C 34272,21512 34580,21820 34960,21820 L 37518,21820 Z"/>
</g>
</g>
<g class="com.sun.star.drawing.ClosedBezierShape">
<g id="id45">
<rect class="BoundingBox" stroke="none" fill="none" x="35066" y="19297" width="5047" height="2331"/>
<path fill="rgb(0,0,0)" fill-opacity="0.251" stroke="rgb(255,255,255)" stroke-opacity="0.251" d="M 37589,21609 L 39750,21609 C 39940,21609 40094,21455 40094,21265 L 40094,19659 C 40094,19469 39940,19315 39750,19315 L 35428,19315 C 35238,19315 35084,19469 35084,19659 L 35084,21265 C 35084,21455 35238,21609 35428,21609 L 37589,21609 Z"/>
<defs>
<mask id="mask11">
<g>
<defs>
<linearGradient id="gradient21" x1="37589" y1="19298" x2="37589" y2="21627" gradientUnits="userSpaceOnUse">
<stop offset="0.5" style="stop-color:rgb(191,191,191)"/>
<stop offset="0.5" style="stop-color:rgb(191,191,191)"/>
<stop offset="1" style="stop-color:rgb(191,191,191)"/>
<stop offset="1" style="stop-color:rgb(191,191,191)"/>
</linearGradient>
</defs>
<path style="fill:url(#gradient21)" d="M 35067,19298 L 40112,19298 40112,21627 35067,21627 35067,19298 Z"/>
</g>
</mask>
</defs>
<g style="mask:url(#mask11)">
<path fill="none" stroke="rgb(0,0,0)" stroke-width="35" stroke-linejoin="miter" d="M 37589,21609 L 39750,21609 C 39940,21609 40094,21455 40094,21265 L 40094,19659 C 40094,19469 39940,19315 39750,19315 L 35428,19315 C 35238,19315 35084,19469 35084,19659 L 35084,21265 C 35084,21455 35238,21609 35428,21609 L 37589,21609 Z"/>
</g>
</g>
</g>
<g class="com.sun.star.drawing.ClosedBezierShape">
<g id="id46">
<rect class="BoundingBox" stroke="none" fill="none" x="34995" y="19191" width="5047" height="2331"/>
<g>
<defs>
<linearGradient id="gradient22" x1="37518" y1="19209" x2="37518" y2="21503" gradientUnits="userSpaceOnUse">
<stop offset="0" style="stop-color:rgb(213,232,212)"/>
<stop offset="1" style="stop-color:rgb(151,208,119)"/>
</linearGradient>
</defs>
<path style="fill:url(#gradient22)" d="M 37518,21503 L 39679,21503 39714,21501 39748,21496 39781,21488 39813,21476 39843,21461 39871,21444 39898,21424 39922,21402 39944,21378 39964,21351 39981,21323 39996,21293 40008,21261 40016,21228 40021,21194 40023,21159 40023,19553 40021,19518 40016,19484 40008,19451 39996,19419 39981,19389 39964,19361 39944,19334 39922,19310 39898,19288 39871,19268 39843,19251 39813,19236 39781,19224 39748,19216 39714,19211 39679,19209 35357,19209 35322,19211 35288,19216 35255,19224 35223,19236 35193,19251 35165,19268 35138,19288 35114,19310 35092,19334 35072,19361 35055,19389 35040,19419 35028,19451 35020,19484 35015,19518 35013,19553 35013,21159 35015,21194 35020,21228 35028,21261 35040,21293 35055,21323 35072,21351 35092,21378 35114,21402 35138,21424 35165,21444 35193,21461 35223,21476 35255,21488 35288,21496 35322,21501 35357,21503 37518,21503 Z"/>
</g>
<path fill="none" stroke="rgb(130,179,102)" stroke-width="35" stroke-linejoin="miter" d="M 37518,21503 L 39679,21503 C 39869,21503 40023,21349 40023,21159 L 40023,19553 C 40023,19363 39869,19209 39679,19209 L 35357,19209 C 35167,19209 35013,19363 35013,19553 L 35013,21159 C 35013,21349 35167,21503 35357,21503 L 37518,21503 Z"/>
</g>
</g>
<g class="com.sun.star.drawing.ClosedBezierShape">
<g id="id47">
<rect class="BoundingBox" stroke="none" fill="none" x="22577" y="17321" width="6529" height="4624"/>
<path fill="rgb(0,0,0)" fill-opacity="0.251" stroke="rgb(255,255,255)" stroke-opacity="0.251" d="M 25841,21926 L 28399,21926 C 28779,21926 29087,21618 29087,21238 L 29087,18027 C 29087,17647 28779,17339 28399,17339 L 23283,17339 C 22903,17339 22595,17647 22595,18027 L 22595,21238 C 22595,21618 22903,21926 23283,21926 L 25841,21926 Z"/>
<defs>
<mask id="mask12">
<g>
<defs>
<linearGradient id="gradient23" x1="25841" y1="17322" x2="25841" y2="21944" gradientUnits="userSpaceOnUse">
<stop offset="0.5" style="stop-color:rgb(191,191,191)"/>
<stop offset="0.5" style="stop-color:rgb(191,191,191)"/>
<stop offset="1" style="stop-color:rgb(191,191,191)"/>
<stop offset="1" style="stop-color:rgb(191,191,191)"/>
</linearGradient>
</defs>
<path style="fill:url(#gradient23)" d="M 22578,17322 L 29105,17322 29105,21944 22578,21944 22578,17322 Z"/>
</g>
</mask>
</defs>
<g style="mask:url(#mask12)">
<path fill="none" stroke="rgb(0,0,0)" stroke-width="35" stroke-linejoin="miter" d="M 25841,21926 L 28399,21926 C 28779,21926 29087,21618 29087,21238 L 29087,18027 C 29087,17647 28779,17339 28399,17339 L 23283,17339 C 22903,17339 22595,17647 22595,18027 L 22595,21238 C 22595,21618 22903,21926 23283,21926 L 25841,21926 Z"/>
</g>
</g>
</g>
<g class="com.sun.star.drawing.ClosedBezierShape">
<g id="id48">
<rect class="BoundingBox" stroke="none" fill="none" x="22507" y="17215" width="6529" height="4624"/>
<g>
<defs>
<linearGradient id="gradient24" x1="25771" y1="17233" x2="25771" y2="21820" gradientUnits="userSpaceOnUse">
<stop offset="0" style="stop-color:rgb(219,250,252)"/>
<stop offset="1" style="stop-color:rgb(125,217,224)"/>
</linearGradient>
</defs>
<path style="fill:url(#gradient24)" d="M 25771,21820 L 28329,21820 28399,21816 28468,21806 28534,21789 28597,21766 28657,21737 28714,21703 28767,21663 28816,21619 28860,21570 28900,21517 28934,21460 28963,21400 28986,21337 29003,21271 29013,21202 29017,21132 29017,17921 29013,17851 29003,17782 28986,17716 28963,17653 28934,17593 28900,17536 28860,17483 28816,17435 28767,17390 28714,17350 28657,17316 28597,17287 28534,17264 28468,17247 28399,17237 28329,17233 23213,17233 23143,17237 23074,17247 23008,17264 22945,17287 22885,17316 22828,17350 22775,17390 22727,17435 22682,17483 22642,17536 22608,17593 22579,17653 22556,17716 22539,17782 22529,17851 22525,17921 22525,21132 22529,21202 22539,21271 22556,21337 22579,21400 22608,21460 22642,21517 22682,21570 22727,21619 22775,21663 22828,21703 22885,21737 22945,21766 23008,21789 23074,21806 23143,21816 23213,21820 25771,21820 Z"/>
</g>
<path fill="none" stroke="rgb(108,142,191)" stroke-width="35" stroke-linejoin="miter" d="M 25771,21820 L 28329,21820 C 28709,21820 29017,21512 29017,21132 L 29017,17921 C 29017,17541 28709,17233 28329,17233 L 23213,17233 C 22833,17233 22525,17541 22525,17921 L 22525,21132 C 22525,21512 22833,21820 23213,21820 L 25771,21820 Z"/>
</g>
</g>
<g class="com.sun.star.drawing.ClosedBezierShape">
<g id="id49">
<rect class="BoundingBox" stroke="none" fill="none" x="23318" y="19297" width="5047" height="2331"/>
<path fill="rgb(0,0,0)" fill-opacity="0.251" stroke="rgb(255,255,255)" stroke-opacity="0.251" d="M 25841,21609 L 28002,21609 C 28192,21609 28346,21455 28346,21265 L 28346,19659 C 28346,19469 28192,19315 28002,19315 L 23680,19315 C 23490,19315 23336,19469 23336,19659 L 23336,21265 C 23336,21455 23490,21609 23680,21609 L 25841,21609 Z"/>
<defs>
<mask id="mask13">
<g>
<defs>
<linearGradient id="gradient25" x1="25841" y1="19298" x2="25841" y2="21627" gradientUnits="userSpaceOnUse">
<stop offset="0.5" style="stop-color:rgb(191,191,191)"/>
<stop offset="0.5" style="stop-color:rgb(191,191,191)"/>
<stop offset="1" style="stop-color:rgb(191,191,191)"/>
<stop offset="1" style="stop-color:rgb(191,191,191)"/>
</linearGradient>
</defs>
<path style="fill:url(#gradient25)" d="M 23319,19298 L 28364,19298 28364,21627 23319,21627 23319,19298 Z"/>
</g>
</mask>
</defs>
<g style="mask:url(#mask13)">
<path fill="none" stroke="rgb(0,0,0)" stroke-width="35" stroke-linejoin="miter" d="M 25841,21609 L 28002,21609 C 28192,21609 28346,21455 28346,21265 L 28346,19659 C 28346,19469 28192,19315 28002,19315 L 23680,19315 C 23490,19315 23336,19469 23336,19659 L 23336,21265 C 23336,21455 23490,21609 23680,21609 L 25841,21609 Z"/>
</g>
</g>
</g>
<g class="com.sun.star.drawing.ClosedBezierShape">
<g id="id50">
<rect class="BoundingBox" stroke="none" fill="none" x="23241" y="19191" width="5047" height="2331"/>
<g>
<defs>
<linearGradient id="gradient26" x1="25764" y1="19209" x2="25764" y2="21503" gradientUnits="userSpaceOnUse">
<stop offset="0" style="stop-color:rgb(213,232,212)"/>
<stop offset="1" style="stop-color:rgb(151,208,119)"/>
</linearGradient>
</defs>
<path style="fill:url(#gradient26)" d="M 25764,21503 L 27925,21503 27960,21501 27994,21496 28027,21488 28059,21476 28089,21461 28117,21444 28144,21424 28168,21402 28190,21378 28210,21351 28227,21323 28242,21293 28254,21261 28262,21228 28267,21194 28269,21159 28269,19553 28267,19518 28262,19484 28254,19451 28242,19419 28227,19389 28210,19361 28190,19334 28168,19310 28144,19288 28117,19268 28089,19251 28059,19236 28027,19224 27994,19216 27960,19211 27925,19209 23603,19209 23568,19211 23534,19216 23501,19224 23469,19236 23439,19251 23411,19268 23384,19288 23360,19310 23338,19334 23318,19361 23301,19389 23286,19419 23274,19451 23266,19484 23261,19518 23259,19553 23259,21159 23261,21194 23266,21228 23274,21261 23286,21293 23301,21323 23318,21351 23338,21378 23360,21402 23384,21424 23411,21444 23439,21461 23469,21476 23501,21488 23534,21496 23568,21501 23603,21503 25764,21503 Z"/>
</g>
<path fill="none" stroke="rgb(130,179,102)" stroke-width="35" stroke-linejoin="miter" d="M 25764,21503 L 27925,21503 C 28115,21503 28269,21349 28269,21159 L 28269,19553 C 28269,19363 28115,19209 27925,19209 L 23603,19209 C 23413,19209 23259,19363 23259,19553 L 23259,21159 C 23259,21349 23413,21503 23603,21503 L 25764,21503 Z"/>
</g>
</g>
<g class="com.sun.star.drawing.TextShape">
<g id="id51">
<rect class="BoundingBox" stroke="none" fill="none" x="24271" y="7895" width="2932" height="1111"/>
<text class="TextShape"><tspan class="TextParagraph" font-family="Helvetica, sans-serif" font-size="776px" font-weight="700"><tspan class="TextPosition" x="24271" y="8767"><tspan fill="rgb(0,0,0)" stroke="none">Log API</tspan></tspan></tspan></text>
</g>
</g>
<g class="com.sun.star.drawing.TextShape">
<g id="id52">
<rect class="BoundingBox" stroke="none" fill="none" x="1076" y="19571" width="4126" height="912"/>
<text class="TextShape"><tspan class="TextParagraph" font-family="Helvetica, sans-serif" font-size="635px" font-weight="700"><tspan class="TextPosition" x="1096" y="20286"><tspan fill="rgb(0,0,0)" stroke="none">Elasticsearch</tspan></tspan></tspan></text>
</g>
</g>
<g class="com.sun.star.drawing.TextShape">
<g id="id53">
<rect class="BoundingBox" stroke="none" fill="none" x="7052" y="18412" width="2687" height="811"/>
<text class="TextShape"><tspan class="TextParagraph" font-family="Helvetica, sans-serif" font-size="564px" font-weight="700"><tspan class="TextPosition" x="7052" y="19047"><tspan fill="rgb(0,0,0)" stroke="none">store logs</tspan></tspan></tspan></text>
</g>
</g>
<g class="com.sun.star.drawing.TextShape">
<g id="id54">
<rect class="BoundingBox" stroke="none" fill="none" x="23352" y="12273" width="4837" height="912"/>
<text class="TextShape"><tspan class="TextParagraph" font-family="Helvetica, sans-serif" font-size="635px" font-weight="700"><tspan class="TextPosition" x="23352" y="12988"><tspan fill="rgb(0,0,0)" stroke="none">Message Queue</tspan></tspan></tspan></text>
</g>
</g>
<g class="com.sun.star.drawing.TextShape">
<g id="id55">
<rect class="BoundingBox" stroke="none" fill="none" x="26353" y="10428" width="5887" height="811"/>
<text class="TextShape"><tspan class="TextParagraph" font-family="Helvetica, sans-serif" font-size="564px" font-weight="700"><tspan class="TextPosition" x="26353" y="11063"><tspan fill="rgb(0,0,0)" stroke="none">publish log messages</tspan></tspan></tspan></text>
</g>
</g>
<g class="com.sun.star.drawing.TextShape">
<g id="id56">
<rect class="BoundingBox" stroke="none" fill="none" x="16238" y="15212" width="3783" height="811"/>
<text class="TextShape"><tspan class="TextParagraph" font-family="Helvetica, sans-serif" font-size="564px" font-weight="700"><tspan class="TextPosition" x="16238" y="15847"><tspan fill="rgb(0,0,0)" stroke="none">consume logs</tspan></tspan></tspan></text>
</g>
</g>
<g class="com.sun.star.drawing.TextShape">
<g id="id57">
<rect class="BoundingBox" stroke="none" fill="none" x="33401" y="15184" width="4160" height="1620"/>
<text class="TextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="564px" font-weight="700"><tspan class="TextPosition" x="33401" y="15819"><tspan font-family="Helvetica, sans-serif" fill="rgb(0,0,0)" stroke="none">f</tspan><tspan fill="rgb(0,0,0)" stroke="none">ilter logs</tspan></tspan></tspan><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="564px" font-weight="700"><tspan class="TextPosition" x="33401" y="16501"><tspan fill="rgb(0,0,0)" stroke="none">publish metrics</tspan></tspan></tspan></text>
</g>
</g>
<g class="com.sun.star.drawing.TextShape">
<g id="id58">
<rect class="BoundingBox" stroke="none" fill="none" x="26046" y="15184" width="2818" height="811"/>
<text class="TextShape"><tspan class="TextParagraph" font-family="Helvetica, sans-serif" font-size="564px" font-weight="700"><tspan class="TextPosition" x="26046" y="15819"><tspan fill="rgb(0,0,0)" stroke="none">parse logs</tspan></tspan></tspan></text>
</g>
</g>
<g class="com.sun.star.drawing.TextShape">
<g id="id59">
<rect class="BoundingBox" stroke="none" fill="none" x="1896" y="254" width="2836" height="1620"/>
<text class="TextShape"><tspan class="TextParagraph" font-family="Helvetica, sans-serif" font-size="564px" font-weight="700"><tspan class="TextPosition" x="3040" y="889"><tspan fill="rgb(0,0,0)" stroke="none">UI</tspan></tspan></tspan><tspan class="TextParagraph" font-family="Helvetica, sans-serif" font-size="564px" font-weight="700"><tspan class="TextPosition" x="1914" y="1698"><tspan fill="rgb(0,0,0)" stroke="none">Kibana 4.4</tspan></tspan></tspan></text>
</g>
</g>
<g class="com.sun.star.drawing.TextShape">
<g id="id60">
<rect class="BoundingBox" stroke="none" fill="none" x="1508" y="2317" width="3381" height="1667"/>
<text class="TextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="494px" font-weight="700"><tspan class="TextPosition" x="2086" y="2766"><tspan fill="rgb(0,0,0)" stroke="none">Keystone</tspan></tspan></tspan><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="494px" font-weight="700"><tspan class="TextPosition" x="1508" y="3321"><tspan fill="rgb(0,0,0)" stroke="none">authentication</tspan></tspan></tspan><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="494px" font-weight="700"><tspan class="TextPosition" x="2456" y="3876"><tspan fill="rgb(0,0,0)" stroke="none">plugin</tspan></tspan></tspan></text>
</g>
</g>
<g class="com.sun.star.drawing.TextShape">
<g id="id61">
<rect class="BoundingBox" stroke="none" fill="none" x="24141" y="0" width="3350" height="1620"/>
<text class="TextShape"><tspan class="TextParagraph" font-family="Helvetica, sans-serif" font-size="564px" font-weight="700"><tspan class="TextPosition" x="24141" y="635"><tspan fill="rgb(0,0,0)" stroke="none">Log Agents</tspan></tspan></tspan></text>
</g>
</g>
<g class="com.sun.star.drawing.TextShape">
<g id="id62">
<rect class="BoundingBox" stroke="none" fill="none" x="23917" y="2433" width="3804" height="1424"/>
<text class="TextShape"><tspan class="TextParagraph" font-family="Helvetica, sans-serif" font-size="494px" font-weight="700"><tspan class="TextPosition" x="23933" y="2992"><tspan fill="rgb(0,0,0)" stroke="none">Monasca output</tspan></tspan></tspan><tspan class="TextParagraph" font-family="Helvetica, sans-serif" font-size="494px" font-weight="700"><tspan class="TextPosition" x="25085" y="3703"><tspan fill="rgb(0,0,0)" stroke="none">plugin</tspan></tspan></tspan></text>
</g>
</g>
<g class="com.sun.star.drawing.TextShape">
<g id="id63">
<rect class="BoundingBox" stroke="none" fill="none" x="3515" y="10428" width="2865" height="811"/>
<text class="TextShape"><tspan class="TextParagraph" font-family="Helvetica, sans-serif" font-size="564px" font-weight="700"><tspan class="TextPosition" x="3515" y="11063"><tspan fill="rgb(0,0,0)" stroke="none">query logs</tspan></tspan></tspan></text>
</g>
</g>
<g class="com.sun.star.drawing.TextShape">
<g id="id64">
<rect class="BoundingBox" stroke="none" fill="none" x="26353" y="5494" width="4507" height="1065"/>
<text class="TextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="635px" font-weight="700"><tspan class="TextPosition" x="26353" y="6070"><tspan fill="rgb(0,0,0)" stroke="none">POST</tspan><tspan fill="rgb(0,0,0)" stroke="none"> </tspan><tspan fill="rgb(0,0,0)" stroke="none">logs</tspan></tspan></tspan></text>
</g>
</g>
<g class="com.sun.star.drawing.TextShape">
<g id="id65">
<rect class="BoundingBox" stroke="none" fill="none" x="11962" y="17539" width="4072" height="912"/>
<text class="TextShape"><tspan class="TextParagraph" font-family="Helvetica, sans-serif" font-size="635px" font-weight="700"><tspan class="TextPosition" x="11962" y="18254"><tspan fill="rgb(0,0,0)" stroke="none">Log Persister</tspan></tspan></tspan></text>
</g>
</g>
<g class="com.sun.star.drawing.TextShape">
<g id="id66">
<rect class="BoundingBox" stroke="none" fill="none" x="35735" y="17439" width="3567" height="912"/>
<text class="TextShape"><tspan class="TextParagraph" font-family="Helvetica, sans-serif" font-size="635px" font-weight="700"><tspan class="TextPosition" x="35735" y="18154"><tspan fill="rgb(0,0,0)" stroke="none">Log Metrics</tspan></tspan></tspan></text>
</g>
</g>
<g class="com.sun.star.drawing.TextShape">
<g id="id67">
<rect class="BoundingBox" stroke="none" fill="none" x="23249" y="17439" width="5032" height="912"/>
<text class="TextShape"><tspan class="TextParagraph" font-family="Helvetica, sans-serif" font-size="635px" font-weight="700"><tspan class="TextPosition" x="23249" y="18154"><tspan fill="rgb(0,0,0)" stroke="none">Log Transformer</tspan></tspan></tspan></text>
</g>
</g>
<g class="com.sun.star.drawing.TextShape">
<g id="id68">
<rect class="BoundingBox" stroke="none" fill="none" x="22894" y="889" width="5843" height="1017"/>
<text class="TextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="494px" font-style="italic" font-weight="700"><tspan class="TextPosition" x="23684" y="1463"><tspan fill="rgb(0,0,0)" stroke="none">Logstash / Beaver</tspan></tspan></tspan></text>
</g>
</g>
<g class="com.sun.star.drawing.TextShape">
<g id="id69">
<rect class="BoundingBox" stroke="none" fill="none" x="23675" y="13281" width="4192" height="807"/>
<text class="TextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="494px" font-style="italic" font-weight="700"><tspan class="TextPosition" x="25098" y="13855"><tspan fill="rgb(0,0,0)" stroke="none">Kafka</tspan></tspan></tspan></text>
</g>
</g>
<g class="com.sun.star.drawing.TextShape">
<g id="id70">
<rect class="BoundingBox" stroke="none" fill="none" x="35359" y="19604" width="4319" height="1906"/>
<text class="TextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="494px" font-weight="700"><tspan class="TextPosition" x="35609" y="20178"><tspan fill="rgb(0,0,0)" stroke="none">IN: Kafka</tspan></tspan></tspan><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="494px" font-weight="700"><tspan class="TextPosition" x="35609" y="20733"><tspan fill="rgb(0,0,0)" stroke="none">OUT: Kafka</tspan></tspan></tspan></text>
</g>
</g>
<g class="com.sun.star.drawing.TextShape">
<g id="id71">
<rect class="BoundingBox" stroke="none" fill="none" x="7052" y="15212" width="5549" height="811"/>
<text class="TextShape"><tspan class="TextParagraph" font-family="Helvetica, sans-serif" font-size="564px" font-weight="700"><tspan class="TextPosition" x="7052" y="15847"><tspan fill="rgb(0,0,0)" stroke="none">query logs (planned)</tspan></tspan></tspan></text>
</g>
</g>
<g class="com.sun.star.drawing.TextShape">
<g id="id72">
<rect class="BoundingBox" stroke="none" fill="none" x="23612" y="19604" width="4319" height="1906"/>
<text class="TextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="494px" font-weight="700"><tspan class="TextPosition" x="23862" y="20178"><tspan fill="rgb(0,0,0)" stroke="none">IN: Kafka</tspan></tspan></tspan><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="494px" font-weight="700"><tspan class="TextPosition" x="23862" y="20733"><tspan fill="rgb(0,0,0)" stroke="none">OUT: Kafka</tspan></tspan></tspan></text>
</g>
</g>
<g class="com.sun.star.drawing.TextShape">
<g id="id73">
<rect class="BoundingBox" stroke="none" fill="none" x="11629" y="19605" width="5898" height="1917"/>
<text class="TextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="494px" font-weight="700"><tspan class="TextPosition" x="11879" y="20179"><tspan fill="rgb(0,0,0)" stroke="none">IN: Kafka</tspan></tspan></tspan><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="494px" font-weight="700"><tspan class="TextPosition" x="11879" y="20734"><tspan fill="rgb(0,0,0)" stroke="none">OUT: Elasticsearch</tspan></tspan></tspan></text>
</g>
</g>
<g class="com.sun.star.drawing.TextShape">
<g id="id74">
<rect class="BoundingBox" stroke="none" fill="none" x="35232" y="18315" width="4573" height="890"/>
<text class="TextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="494px" font-style="italic" font-weight="700"><tspan class="TextPosition" x="36422" y="18889"><tspan fill="rgb(0,0,0)" stroke="none">Logstash</tspan></tspan></tspan></text>
</g>
</g>
<g class="com.sun.star.drawing.TextShape">
<g id="id75">
<rect class="BoundingBox" stroke="none" fill="none" x="11702" y="18415" width="4573" height="890"/>
<text class="TextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="494px" font-style="italic" font-weight="700"><tspan class="TextPosition" x="12892" y="18989"><tspan fill="rgb(0,0,0)" stroke="none">Logstash</tspan></tspan></tspan></text>
</g>
</g>
<g class="com.sun.star.drawing.TextShape">
<g id="id76">
<rect class="BoundingBox" stroke="none" fill="none" x="23478" y="18315" width="4573" height="890"/>
<text class="TextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="494px" font-style="italic" font-weight="700"><tspan class="TextPosition" x="24668" y="18889"><tspan fill="rgb(0,0,0)" stroke="none">Logstash</tspan></tspan></tspan></text>
</g>
</g>
</g>
</g>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 106 KiB

View File

@ -1,6 +0,0 @@
======================
Administration guide
======================
.. toctree::
:maxdepth: 2

View File

@ -1,6 +0,0 @@
========================
Command Line Interface
========================
At the moment, monasca-log-api cannot be operated
from the CLI.

View File

@ -1,281 +0,0 @@
# -*- coding: utf-8 -*-
#
# monasca-log-api documentation build configuration file, created by
# sphinx-quickstart on Wed Nov 18 12:02:03 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.
import os
import sys
sys.path = [
os.path.abspath('../..'),
os.path.abspath('../../bin')
] + sys.path
# -- General configuration ------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
needs_sphinx = '1.6'
# 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.coverage',
'sphinx.ext.ifconfig',
'sphinx.ext.graphviz',
'sphinx.ext.autodoc',
'sphinx.ext.viewcode',
'oslo_config.sphinxconfiggen',
'oslo_config.sphinxext',
'openstackdocstheme',
'oslo_policy.sphinxpolicygen'
]
# geeneral information about project
openstackdocs_repo_name = u'openstack/monasca-log-api'
openstackdocs_auto_name = False
project = u'Monasca Log Dev Docs'
openstackdocs_bug_project = u'monasca-log-api'
openstackdocs_bug_tag = u'doc'
copyright = u'2014-present, OpenStack Foundation'
author = u'OpenStack Foundation'
# sample config
config_generator_config_file = [
('config-generator/monasca-log-api.conf', '_static/monasca-log-api')
]
policy_generator_config_file = [
('config-generator/policy.conf', '_static/log-api')
]
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# The suffix(es) of source filenames.
source_suffix = '.rst'
# The encoding of source files.
source_encoding = 'utf-8'
# The master toctree document.
master_doc = 'index'
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
exclude_patterns = [
'common',
'doc',
'documentation',
'etc',
'java'
]
# 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 = True
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'native'
# A list of ignored prefixes for module index sorting.
modindex_common_prefix = ['monasca_log_api.', 'monasca']
# -- 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 = 'openstackdocs'
# 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
# doc. 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 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 false, no module index is generated.
html_use_modindex = 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
# Language to be used for generating the HTML full-text search index.
# Sphinx supports the following languages:
# 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja'
# 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr'
#html_search_language = 'en'
# A dictionary with options for the search language support, empty by default.
# Now only 'ja' uses this config value
#html_search_options = {'type': 'default'}
# The name of a javascript file (relative to the configuration directory) that
# implements a search results scorer. If empty, the default will be used.
#html_search_scorer = 'scorer.js'
# Output file base name for HTML help builder.
htmlhelp_basename = 'monasca-log-apidoc'
# -- 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': '',
# Latex figure (float) alignment
#'figure_align': 'htbp',
}
# 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 = [
(master_doc, 'monasca-log-api.tex', u'monasca-log-api Documentation',
u'Openstack Foundation \\textless{}monasca@lists.launchpad.net\\textgreater{}', '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 = [
(master_doc, 'monasca-log-api', u'monasca-log-api Documentation',
[author], 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 = [
(master_doc, 'monasca-log-api', u'monasca-log-api Documentation',
author, 'monasca-log-api', 'Rest-API to collect logs from your cloud.',
'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
# Example configuration for intersphinx: refer to the Python standard library.
intersphinx_mapping = {'https://doc.python.org/': None}

View File

@ -1,160 +0,0 @@
.. _basic-configuration:
-----------
Configuring
-----------
monasca-log-api has several configuration options. Some of them
are inherited from oslo libraries, others can be found in the monasca-log-api
codebase.
The entire configuration of monasca-log-api is defined in
configuration files.
.. note:: This is intended behaviour. One of possible ways to deploy
monasca-log-api is to use **gunicorn**. Unfortunately gunicorn's
argument parsing clashes with oslo's argument parsing.
This means that gunicorn reports the CLI options of
oslo as unknown, and vice versa.
There are 4 configuration files. For more details on the configuration
options, see :ref:`here <configuration-files>`.
Configuring Keystone Authorization
----------------------------------
Keystone authorization (i.e. verification of the token associated
with a request) is a critical part of monasca-log-api.
It prevents from unauthorized access and provides the isolation
needed for multi-tenancy.
The configuration for ``keystonemiddleware`` should either be provided in
``monasca-log-api.conf`` or in a file in one of the configuration directories.
For more details about configuration options, check
`here <https://docs.openstack.org/keystonemiddleware/latest/middlewarearchitecture.html#configuration>`_.
Configuring Log Publishing
--------------------------
monasca-log-api sends all logs to the Kafka Message Queue.
Proper configuration should include:
* ``kafka_url`` - comma-delimited list of Kafka brokers
* ``topics`` - names of the topics to which the logs will be pushed to
* ``max_message_size`` - maximum message size that can be posted a topic
The configuration for ``log_publisher`` should either be provided in
``monasca-log-api.conf`` or in a file in one of the configuration directories.
Configuring Healthcheck
-----------------------
Healthcheck is an essential part of monasca-log-api.
It allows sending HTTP requests and getting knowledge about the
availability of the API. Configuration of healthcheck includes:
* ``kafka_url`` - comma-delimited list of Kafka brokers
* ``kafka_topics`` - list of topics that existence is verified by healthcheck
The configuration for ``kafka_healthcheck`` should either be provided in
``monasca-log-api.conf`` or in a file in one of the configuration directories.
Configuring Monitoring
----------------------
monasca-log-api is capable of self-monitoring. This is achieved
through `monasca-statsd <https://github.com/openstack/monasca-statsd>`_.
It assumes that there is monasca-agent available on the system node and
that statsd-server has been launched.
There are several options you may want to tweak if necessary:
* ``statsd_host``- the host statsd-server is bound to
* ``statsd_port``- the port statsd-server is bound to
* ``statsd_buffer`` - the amount of metrics to buffer in memory before sending
any
* ``dimensions`` - additional dimensions to be sent with all
metrics for this monasca-log-api instance
The configuration for ``monitoring`` should either be provided in
``monasca-log-api.conf`` or in a file in one of the configuration directories.
Configuring RBAC
----------------
The role-based access policy can be defined in the ``log-api.policy.yaml`` file
as described in `oslo.policy documentation
<https://docs.openstack.org/oslo.policy>`_.
Additionally, for historical reasons, custom RBAC mechanism is provided. It can
be configured as follows:
* ``path`` - list of URIs that RBAC applies to
* ``default_roles`` - list of roles that are permitted to access the API
* ``agent_roles`` - list of roles, that if present, means that requests come
from log-agent
* ``delegate_roles`` - list of roles required by log-agent for sending logs
on behalf of another project (tenant)
The configuration for ``roles_middleware`` can be provided either in
``monasca-log-api.conf`` or in a file in one of the configuration directories.
Configuring Logging
-------------------
Logging in monasca-log-api is controlled from the single
``log-api-logging.conf`` configuration file.
Here is a short list of several modifications you may want to apply,
based on your deployment:
* to log INFO to console::
[handler_console]
level = INFO
* to log DEBUG to file::
[handler_file]
level = DEBUG
* to change the log file location::
[handler_file]
args = ('/var/log/log-api.log', 'a')
* if you have an external script for log rotation::
[handler_file]
handler = logging.handlers.WatchedFileHandler
args = ('/var/log/log-api.log', 'a')
That will store up to 5 rotations (each having maximum size
of 100MBs)
The configuration of ``logging`` should be presented inside
``log-api-logging.conf`` file and referenced from ``monasca-log-api.conf``
using ``log_config_append`` option.
If you want to know more about possible ways to save monasca-log-api logs,
feel free to visit:
* `oslo.log <https://docs.openstack.org/oslo.log/latest/index.html>`_
* `Python HowTo <https://docs.python.org/2/howto/logging.html>`_
* `Logging handlers <https://docs.python.org/2/library/logging.handlers.html>`_
Configuring Policies
--------------------
The policies for accessing each service can be configured in the
``log-api.policy.yaml`` configuration file::
Policy Description
Method Path
"Policy string": "Roles"
example::
Logs post rule
POST /logs
POST /log/single
"log_api:logs:post": "role:monasca-user"

View File

@ -1,99 +0,0 @@
.. _configuration-files:
-------------------
Configuration files
-------------------
Overview of monasca-log-api's configuration files.
monasca-log-api.conf
--------------------
This is the main configuration file of monasca-log-api.
It can be located in several places. During startup,
monasca-log-api searches for it in the following directories:
* ``~/.monasca``
* ``~/``
* ``/etc/monasca``
* ``/etc``
Alternatively, you can roll with a multi-file-based configuration model.
In this case, monasca-log-api searches the configuration files
in the following directories:
* ``~/.monasca/monasca.conf.d/``
* ``~/.monasca/monasca-log-api.conf.d/``
* ``~/monasca.conf.d/``
* ``~/monasca-log-api.conf.d/``
* ``/etc/monasca/monasca.conf.d/``
* ``/etc/monasca/monasca-log-api.conf.d/``
* ``/etc/monasca.conf.d/``
* ``/etc/monasca-log-api.conf.d/``
Regardless of the location, the name of the main configuration file
should always be ``monasca-log-api.conf``. For files located
in ``.conf.d`` directories, the name is irrelevant, but it should
indicate the file content.
For example, when guring keystone communication. The
`keystonemiddleware <https://docs.openstack.org/keystonemiddleware/latest/>`_
configuration would be, therefore, located in, for example,
``/etc/monasca-log-api.conf.d/keystonemiddleware.conf``
A sample of this configuration file is also available
:ref:`here <sample-configuration-api>`
log-api-logging.conf
--------------------
This file contains the logging setup for monasca-log-api. It should be
referenced from ``monasca-log-api.conf`` using, for example,
the following code snippet::
[DEFAULT]
log_config_append = /etc/monasca/log-api-logging.conf
A sample of this configuration file is also available
:ref:`here <sample-configuration-logging>`
log-api-paste.ini
-----------------
This file contains the `PasteDeploy <http://pastedeploy.readthedocs.io/en/latest/>`_
configuration. It describes all pipelines that are running within a single
instance of monasca-log-api.
There is nothing you should try and modify in this file,
apart from enabling/disabling ``oslo_middleware.debug:Debug``.
To enable ``oslo_middleware.debug:Debug`` for ``Log v3`` pipeline,
``log-api-paste.ini`` should contain code similar to this one::
[composite:main]
use = egg:Paste#urlmap
/v3.0: la_api_v3
[pipeline:la_api_v3]
pipeline = debug {{ other pipeline members }}
[filter:debug]
paste.filter_factory = oslo_middleware.debug:Debug.factory
This particular filter might be useful for examining the
WSGI environment during troubleshooting or local development.
log-api.policy.yaml
-------------------
This is the configuration file for policies to access the services.
the path of the file can be defined in ``monasca-log-api.conf``::
[oslo_policy]
policy_file = log-api.policy.yaml
More information about policy file configuration can be found at
`oslo.policy <https://docs.openstack.org/oslo.policy/latest/admin/policy-yaml-file.html>`_
A sample of this configuration file is also available
:ref:`here <sample-configuration-policy>`

View File

@ -1,17 +0,0 @@
.. _configuring:
=============
Configuration
=============
This section describes the configuration settings that can be specified.
Refer to :ref:`basic-configuration` for more details on the
available settings.
.. toctree::
:maxdepth: 1
configuring
files
options
sample

View File

@ -1,8 +0,0 @@
.. _monasca-log-api.conf:
-------
Options
-------
.. show-options::
:config-file: config-generator/monasca-log-api.conf

View File

@ -1,51 +0,0 @@
.. _sample-configuration:
-------
Samples
-------
The following sections show sample configuration files for monasca-log-api and
related utilities. These are generated from the code
(apart from the samples for logging and paster) and reflect the current state
of code in the monasca-log-api repository.
.. _sample-configuration-api:
Sample Configuration For Application
------------------------------------
This sample configuration can also be viewed in `monasca-log-api.conf.sample
<../_static/monasca-log-api.conf.sample>`_.
.. literalinclude:: ../_static/monasca-log-api.conf.sample
.. _sample-configuration-logging:
Sample Configuration For Logging
--------------------------------
This sample configuration can also be viewed in `log-api-logging.conf
<https://github.com/openstack/monasca-log-api/blob/master/etc/monasca/log-api-logging.conf>`_.
.. literalinclude:: ../../../etc/monasca/log-api-logging.conf
Sample Configuration For Paste
------------------------------
This sample configuration can also be viewed in `log-api-paste.ini
<https://github.com/openstack/monasca-log-api/blob/master/etc/monasca/log-api-paste.ini>`_.
.. literalinclude:: ../../../etc/monasca/log-api-paste.ini
.. _sample-configuration-policy:
Sample Configuration For Policy
-------------------------------
This sample configuration can also be viewed in `log-api-policy.yaml.sample
<../_static/log-api-policy.yaml.sample>`_.
.. literalinclude:: ../_static/log-api.policy.yaml.sample

View File

@ -1,3 +0,0 @@
# codebase documentation is autogenerated
# so we do not want to track it in the tree
api/

View File

@ -1,18 +0,0 @@
.. _codedocs:
======================
Codebase documentation
======================
Following section contains codebase documenation generated with, a little
bit of assistance, `sphinx.ext.autodoc`_.
.. _`sphinx.ext.autodoc`: http://www.sphinx-doc.org/en/stable/ext/autodoc.html
Modules
=======
.. toctree::
:maxdepth: 2
api/autoindex.rst

View File

@ -1,30 +0,0 @@
=======================
Contribution Guidelines
=======================
In the Contributions Guide, you will find documented policies for
developing with monasca-log. This includes the processes we use for
blueprints and specs, bugs, contributor onboarding, core reviewer
memberships, and other procedural items.
monasca-log, as with all OpenStack projects, is written with the following
design guidelines in mind:
* **Component based architecture**: Quickly add new behaviors
* **Highly available**: Scale to very serious workloads
* **Fault tolerant**: Isolated processes avoid cascading failures
* **Recoverable**: Failures should be easy to diagnose, debug, and rectify
* **Open standards**: Be a reference implementation for a community-driven api
This documentation is generated by the Sphinx toolkit and lives in the source
tree. Additional documentation on monasca-log and other components of
OpenStack can be found on the `OpenStack wiki <http://wiki.openstack.org>`_.
Developer reference
-------------------
.. toctree::
:maxdepth: 1
tox
code

View File

@ -1,77 +0,0 @@
..
monasca-log-api documentation master file
Copyright 2017 FUJITSU LIMITED
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.
.. _`tox`: https://tox.readthedocs.io/en/latest/
.. _`mandatory_tox_env`: https://github.com/openstack/monasca-log-api/blob/master/tox.ini#L2
===
Tox
===
**monasca-log-api** uses `tox`_ to wrap up all the activities around
testing and linting the codebase.
List of environments
====================
There is a rather large number of tox environments that **monasca-log-api**
is using. If necessary they can be enlisted with::
tox -a -v
An output will be similar to this::
default environments:
py27 -> Runs unit test using Python2.7
py35 -> Runs unit test using Python3.5
pep8 -> Runs set of linters against codebase (flake8, bandit,
bashate, checkniceness)
cover -> Calculates code coverage
additional environments:
api-guide -> Called from CI scripts to test and publish the API Guide
api-ref -> Called from CI scripts to test and publish the API Ref
apidocs -> Generates codebase documentation
bandit -> [no description]
bashate -> Validates (pep8-like) devstack plugins
checkjson -> Validates all json samples inside doc folder
checkniceness -> Validates (pep-like) documenation
debug -> Allows to run unit-test with debug mode enabled
docs -> Builds api-ref, api-guide, releasenotes and doc
flake8 -> [no description]
releasenotes -> Called from CI script to test and publish the Release Notes
venv -> [no description]
Running tox
===========
Running tox is as simple as::
tox
That will run all **mandatory** (for details refer to `mandatory_tox_env`_)
environments. Having them passed is *a must have*.
Running specific environments
=============================
If you require to run specific environments, please use::
tox -e api-ref,api-guide,releasenotes
Result of which will be having all documentations sub-components generated
and ready in local dev environment.

View File

@ -1,6 +0,0 @@
.. note:: The Log API v2 has been DEPRECATED in the Mitaka release. The
migration path is to use the `Log API v3
<https://docs.openstack.org/api-ref/monitoring-log-api/#logs>`_ instead of version 2
of the API. The Log API v2 will ultimately be removed, following the
`OpenStack standard deprecation policy
<https://governance.openstack.org/reference/tags/assert_follows-standard-deprecation.html>`_.

View File

@ -1,3 +0,0 @@
========
Glossary
========

View File

@ -1,50 +0,0 @@
..
monasca-log-api documentation master file
Copyright 2016-2017 FUJITSU LIMITED
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.
===========================================
Welcome to monasca-log-api's documentation!
===========================================
monasca-log-api is a RESTful API server acting as gateway for
logs collected from log-agents.
.. include:: deprecation_note.inc
The developer documentation provided here is continually kept up-to-date
based on the latest code, and may not represent the state of the project at
any specific prior release.
.. note:: This is documentation for developers, if you are looking for more
general documentation including API, install, operator and user
guides see `docs.openstack.org`_
.. _`docs.openstack.org`: https://docs.openstack.org
.. toctree::
:maxdepth: 2
user/index
admin/index
install/index
configuration/index
cli/index
contributor/index
.. toctree::
:maxdepth: 1
glossary

View File

@ -1,6 +0,0 @@
==============
Installation
==============
.. toctree::
:maxdepth: 2

View File

@ -1,6 +0,0 @@
============
User guide
============
.. toctree::
:maxdepth: 2

View File

@ -1,57 +0,0 @@
ARG DOCKER_IMAGE=monasca/log-api
ARG APP_REPO=https://review.opendev.org/openstack/monasca-log-api
# Branch, tag or git hash to build from.
ARG REPO_VERSION=master
ARG CONSTRAINTS_BRANCH=master
# Extra Python3 dependencies.
ARG EXTRA_DEPS="gunicorn python-memcached gevent"
# Always start from `monasca-base` image and use specific tag of it.
ARG BASE_TAG=master
FROM monasca/base:$BASE_TAG
# Environment variables used for our service or wait scripts.
ENV \
KAFKA_URI=kafka:9092 \
KAFKA_WAIT_FOR_TOPICS=log \
MONASCA_CONTAINER_LOG_API_PORT=5607 \
MEMCACHED_URI=memcached:11211 \
AUTHORIZED_ROLES=admin,domainuser,domainadmin,monasca-user \
AGENT_AUTHORIZED_ROLES=monasca-agent \
KEYSTONE_IDENTITY_URI=http://keystone:35357 \
KEYSTONE_AUTH_URI=http://keystone:5000 \
KEYSTONE_ADMIN_USER=admin \
KEYSTONE_ADMIN_PASSWORD=secretadmin \
KEYSTONE_ADMIN_TENANT=admin \
KEYSTONE_ADMIN_DOMAIN=default \
GUNICORN_WORKERS=9 \
GUNICORN_WORKER_CLASS=gevent \
GUNICORN_WORKER_CONNECTIONS=2000 \
GUNICORN_BACKLOG=1000 \
GUNICORN_TIMEOUT=10 \
PYTHONIOENCODING=utf-8 \
ADD_ACCESS_LOG=false \
ACCESS_LOG_FORMAT="%(asctime)s [%(process)d] gunicorn.access [%(levelname)s] %(message)s" \
ACCESS_LOG_FIELDS='%(h)s %(l)s %(u)s %(t)s %(r)s %(s)s %(b)s "%(f)s" "%(a)s" %(L)s' \
LOG_LEVEL_ROOT=INFO \
LOG_LEVEL_CONSOLE=INFO \
LOG_LEVEL_ACCESS=INFO \
STAY_ALIVE_ON_FAILURE="false"
# Copy all neccessary files to proper locations.
COPY log-api* monasca-log-api* /etc/monasca/
# Run here all additionals steps your service need post installation.
# Stay with only one `RUN` and use `&& \` for next steps to don't create
# unnecessary image layers. Clean at the end to conserve space.
#RUN \
# echo "Some steps to do after main installation." && \
# echo "Hello when building."
# Expose port for specific service.
EXPOSE ${MONASCA_CONTAINER_LOG_API_PORT}
# Implement start script in `start.sh` file.
CMD ["/start.sh"]

View File

@ -1,85 +0,0 @@
================================
Docker image for Monasca Log API
================================
The Monasca log API image is based on the monasca-base image.
Building monasca-base image
===========================
See https://github.com/openstack/monasca-common/tree/master/docker/README.rst
Building Monasca log API image
==============================
Example:
$ ./build_image.sh <repository_version> <upper_constains_branch> <common_version>
Requirements from monasca-base image
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
health_check.py
This file will be used for checking the status of the Monasca Log API
application.
Scripts
~~~~~~~
start.sh
In this starting script provide all steps that lead to the proper service
start. Including usage of wait scripts and templating of configuration
files. You also could provide the ability to allow running container after
service died for easier debugging.
build_image.sh
Please read detailed build description inside the script.
Environment variables
~~~~~~~~~~~~~~~~~~~~~
============================== ======================================================================= ==========================================
Variable Default Description
============================== ======================================================================= ==========================================
KAFKA_URI kafka:9092 URI to Apache Kafka (distributed streaming platform)
KAFKA_WAIT_FOR_TOPICS log The topic where log-api streams the log messages
KAFKA_WAIT_RETRIES 24 Number of kafka connect attempts
KAFKA_WAIT_DELAY 5 Seconds to wait between attempts
MONASCA_CONTAINER_LOG_API_PORT 5607 The port from the log pipeline endpoint
MEMCACHED_URI memcached:11211 URI to Keystone authentication cache
AUTHORIZED_ROLES admin,domainuser,domainadmin,monasca-user Roles for Monasca users (full API access)
AGENT_AUTHORIZED_ROLES monasca-agent Roles for Monasca agents (sending data only)
KEYSTONE_IDENTITY_URI http://keystone:35357 URI to Keystone admin endpoint
KEYSTONE_AUTH_URI http://keystone:5000 URI to Keystone public endpoint
KEYSTONE_ADMIN_USER admin OpenStack administrator user name
KEYSTONE_ADMIN_PASSWORD secretadmin OpenStack administrator user password
KEYSTONE_ADMIN_TENANT admin OpenStack administrator tenant name
KEYSTONE_ADMIN_DOMAIN default OpenStack administrator domain
GUNICORN_WORKERS 9 Number of gunicorn (WSGI-HTTP server) workers
GUNICORN_WORKER_CLASS gevent Used gunicorn worker class
GUNICORN_WORKER_CONNECTIONS 2000 Number of gunicorn worker connections
GUNICORN_BACKLOG 1000 Number of gunicorn backlogs
GUNICORN_TIMEOUT 10 Gunicorn connection timeout
PYTHONIOENCODING utf-8 Python encoding
ADD_ACCESS_LOG false Enable gunicorn request/access logging
ACCESS_LOG_FORMAT "%(asctime)s [%(process)d] gunicorn.access [%(levelname)s] %(message)s" Define the logging format
ACCESS_LOG_FIELDS '%(h)s %(l)s %(u)s %(t)s %(r)s %(s)s %(b)s "%(f)s" "%(a)s" %(L)s' Define the fields to be logged
LOG_LEVEL_ROOT WARN Log level for root logging
LOG_LEVEL_CONSOLE INFO Log level for console logging
LOG_LEVEL_ACCESS INFO Log level for access logging
STAY_ALIVE_ON_FAILURE false If true, container runs 2 hours after tests fail
============================== ======================================================================= ==========================================
Provide configuration templates
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* monasca-log-api.conf.j2
* log-api-gunicorn.conf.j2
* log-api-logging.conf.j2
* log-api.paste.ini.j2
Links
~~~~~
https://docs.openstack.org/monasca-log-api/latest/configuration/
https://github.com/openstack/monasca-log-api/blob/master/README.rst

View File

@ -1,150 +0,0 @@
#!/bin/bash
# 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.
# TODO(Dobroslaw): move this script to monasca-common/docker folder
# and leave here small script to download it and execute using env variables
# to minimize code duplication.
set -x # Print each script step.
set -eo pipefail # Exit the script if any statement returns error.
# This script is used for building Docker image with proper labels
# and proper version of monasca-common.
#
# Example usage:
# $ ./build_image.sh <repository_version> <upper_constains_branch> <common_version>
#
# Everything after `./build_image.sh` is optional and by default configured
# to get versions from `Dockerfile`.
#
# To build from master branch (default):
# $ ./build_image.sh
# To build specific version run this script in the following way:
# $ ./build_image.sh stable/queens
# Building from specific commit:
# $ ./build_image.sh cb7f226
# When building from a tag monasca-common will be used in version available
# in upper constraint file:
# $ ./build_image.sh 2.5.0
# To build image from Gerrit patch sets that is targeting branch stable/queens:
# $ ./build_image.sh refs/changes/51/558751/1 stable/queens
#
# If you want to build image with custom monasca-common version you need
# to provide it as in the following example:
# $ ./build_image.sh master master refs/changes/19/595719/3
# Go to folder with Docker files.
REAL_PATH=$(python -c "import os,sys; print(os.path.realpath('$0'))")
cd "$(dirname "$REAL_PATH")/../docker/"
[ -z "$DOCKER_IMAGE" ] && \
DOCKER_IMAGE=$(\grep DOCKER_IMAGE Dockerfile | cut -f2 -d"=")
: "${REPO_VERSION:=$1}"
[ -z "$REPO_VERSION" ] && \
REPO_VERSION=$(\grep REPO_VERSION Dockerfile | cut -f2 -d"=")
# Let's stick to more readable version and disable SC2001 here.
# shellcheck disable=SC2001
REPO_VERSION_CLEAN=$(echo "$REPO_VERSION" | sed 's|/|-|g')
[ -z "$APP_REPO" ] && APP_REPO=$(\grep APP_REPO Dockerfile | cut -f2 -d"=")
GITHUB_REPO=$(echo "$APP_REPO" | sed 's/review.opendev.org/github.com/' | \
sed 's/ssh:/https:/')
if [ -z "$CONSTRAINTS_FILE" ]; then
CONSTRAINTS_FILE=$(\grep CONSTRAINTS_FILE Dockerfile | cut -f2 -d"=") || true
: "${CONSTRAINTS_FILE:=https://releases.openstack.org/constraints/upper/master}"
fi
: "${CONSTRAINTS_BRANCH:=$2}"
[ -z "$CONSTRAINTS_BRANCH" ] && \
CONSTRAINTS_BRANCH=$(\grep CONSTRAINTS_BRANCH Dockerfile | cut -f2 -d"=")
# When using stable version of repository use same stable constraints file.
case "$REPO_VERSION" in
*stable*)
CONSTRAINTS_BRANCH_CLEAN="$REPO_VERSION"
CONSTRAINTS_FILE=${CONSTRAINTS_FILE/master/$CONSTRAINTS_BRANCH_CLEAN}
# Get monasca-common version from stable upper constraints file.
CONSTRAINTS_TMP_FILE=$(mktemp)
wget --output-document "$CONSTRAINTS_TMP_FILE" \
$CONSTRAINTS_FILE
UPPER_COMMON=$(\grep 'monasca-common' "$CONSTRAINTS_TMP_FILE")
# Get only version part from monasca-common.
UPPER_COMMON_VERSION="${UPPER_COMMON##*===}"
rm -rf "$CONSTRAINTS_TMP_FILE"
;;
*)
CONSTRAINTS_BRANCH_CLEAN="$CONSTRAINTS_BRANCH"
;;
esac
# Monasca-common variables.
if [ -z "$COMMON_REPO" ]; then
COMMON_REPO=$(\grep COMMON_REPO Dockerfile | cut -f2 -d"=") || true
: "${COMMON_REPO:=https://review.opendev.org/openstack/monasca-common}"
fi
: "${COMMON_VERSION:=$3}"
if [ -z "$COMMON_VERSION" ]; then
COMMON_VERSION=$(\grep COMMON_VERSION Dockerfile | cut -f2 -d"=") || true
if [ "$UPPER_COMMON_VERSION" ]; then
# Common from upper constraints file.
COMMON_VERSION="$UPPER_COMMON_VERSION"
fi
fi
# Clone project to temporary directory for getting proper commit number from
# branches and tags. We need this for setting proper image labels.
# Docker does not allow to get any data from inside of system when building
# image.
TMP_DIR=$(mktemp -d)
(
cd "$TMP_DIR"
# This many steps are needed to support gerrit patch sets.
git init
git remote add origin "$APP_REPO"
git fetch origin "$REPO_VERSION"
git reset --hard FETCH_HEAD
)
GIT_COMMIT=$(git -C "$TMP_DIR" rev-parse HEAD)
[ -z "${GIT_COMMIT}" ] && echo "No git commit hash found" && exit 1
rm -rf "$TMP_DIR"
# Do the same for monasca-common.
COMMON_TMP_DIR=$(mktemp -d)
(
cd "$COMMON_TMP_DIR"
# This many steps are needed to support gerrit patch sets.
git init
git remote add origin "$COMMON_REPO"
git fetch origin "$COMMON_VERSION"
git reset --hard FETCH_HEAD
)
COMMON_GIT_COMMIT=$(git -C "$COMMON_TMP_DIR" rev-parse HEAD)
[ -z "${COMMON_GIT_COMMIT}" ] && echo "No git commit hash found" && exit 1
rm -rf "$COMMON_TMP_DIR"
CREATION_TIME=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
docker build --no-cache \
--build-arg CREATION_TIME="$CREATION_TIME" \
--build-arg GITHUB_REPO="$GITHUB_REPO" \
--build-arg APP_REPO="$APP_REPO" \
--build-arg REPO_VERSION="$REPO_VERSION" \
--build-arg GIT_COMMIT="$GIT_COMMIT" \
--build-arg CONSTRAINTS_FILE="$CONSTRAINTS_FILE" \
--build-arg COMMON_REPO="$COMMON_REPO" \
--build-arg COMMON_VERSION="$COMMON_VERSION" \
--build-arg COMMON_GIT_COMMIT="$COMMON_GIT_COMMIT" \
--tag "$DOCKER_IMAGE":"$REPO_VERSION_CLEAN" .

View File

@ -1,45 +0,0 @@
#!/usr/bin/env python
# coding=utf-8
# (C) Copyright 2018 FUJITSU LIMITED
#
# 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.
"""Health check will returns 0 when service is working properly."""
import logging
import os
import sys
from urllib import request
LOG_LEVEL = logging.getLevelName(os.environ.get('LOG_LEVEL', 'INFO'))
logging.basicConfig(level=LOG_LEVEL)
logger = logging.getLogger(__name__)
API_PORT = os.environ.get('MONASCA_CONTAINER_LOG_API_PORT', '5607')
url = "http://localhost:" + API_PORT + "/healthcheck"
def main():
"""Send health check request to health check endpoint of log API."""
logger.debug('Send health check request to %s', url)
try:
request.urlopen(url=url)
except Exception as ex:
logger.error('Exception during request handling: ' + repr(ex))
sys.exit(1)
if __name__ == '__main__':
main()

View File

@ -1,13 +0,0 @@
bind = '0.0.0.0:{{ MONASCA_CONTAINER_LOG_API_PORT }}'
proc_name = 'monasca-log-api'
backlog = {{ GUNICORN_BACKLOG | int }}
workers = {{ GUNICORN_WORKERS | int }}
worker_class = '{{ GUNICORN_WORKER_CLASS }}'
timeout = {{ GUNICORN_TIMEOUT | int }}
{% if ADD_ACCESS_LOG == true %}
accesslog = '-'
access_log_format = '{{ ACCESS_LOG_FIELDS }}'
{% endif %}
capture_output = True

View File

@ -1,47 +0,0 @@
[default]
disable_existing_loggers = 0
[loggers]
keys = root, gunicorn_access, kafka
[handlers]
keys = console, gunicorn_access
[formatters]
keys = context, gunicorn_access
[logger_root]
level = {{ LOG_LEVEL_ROOT }}
handlers = console
[logger_gunicorn_access]
level = {{ LOG_LEVEL_ACCESS }}
handlers = console
propagate = 0
qualname = gunicorn.access
[logger_kafka]
qualname = kafka
level = DEBUG
handlers = console
propagate = 0
[handler_console]
class = logging.StreamHandler
args = (sys.stdout,)
level = {{ LOG_LEVEL_CONSOLE }}
formatter = context
[handler_gunicorn_access]
class = logging.StreamHandler
args = (sys.stdout,)
level = {{ LOG_LEVEL_ACCESS }}
formatter = gunicorn_access
[formatter_context]
class = oslo_log.formatters.ContextFormatter
[formatter_gunicorn_access]
class = logging.Formatter
format = {{ ACCESS_LOG_FORMAT }}
datefmt = %Y-%m-%d %H:%M:%S

View File

@ -1,53 +0,0 @@
[DEFAULT]
name = monasca_log_api
[composite:main]
use = egg:Paste#urlmap
/: la_version
/healthcheck: la_healthcheck
/v2.0: la_api_v2
/v3.0: la_api_v3
[pipeline:la_version]
pipeline = error_trap versionapp
[pipeline:la_healthcheck]
pipeline = error_trap healthcheckapp
[pipeline:la_api_v2]
pipeline = error_trap request_id auth roles api_v2_app
[pipeline:la_api_v3]
pipeline = error_trap request_id auth roles api_v3_app
[app:versionapp]
paste.app_factory = monasca_log_api.app.api:create_version_app
[app:healthcheckapp]
paste.app_factory = monasca_log_api.app.api:create_healthcheck_app
[app:api_v2_app]
paste.app_factory = monasca_log_api.app.api:create_api_app
set api_version=v2.0
[app:api_v3_app]
paste.app_factory = monasca_log_api.app.api:create_api_app
set api_version=v3.0
[filter:auth]
paste.filter_factory = keystonemiddleware.auth_token:filter_factory
[filter:roles]
paste.filter_factory = monasca_log_api.middleware.role_middleware:RoleMiddleware.factory
[filter:request_id]
paste.filter_factory = oslo_middleware.request_id:RequestId.factory
[filter:debug]
paste.filter_factory = oslo_middleware.debug:Debug.factory
[filter:error_trap]
paste.filter_factory = oslo_middleware.catch_errors:CatchErrors.factory
[server:main]
use = egg:gunicorn#main

View File

@ -1,42 +0,0 @@
[DEFAULT]
log_config_append=/etc/monasca/log-api-logging.conf
[monitoring]
enable = {{ MONITORING_ENABLE | default(False) }}
statsd_host = {{ STATSD_HOST | default('127.0.0.1') }}
statsd_port = {{ STATSD_PORT | default(8125) }}
statsd_buffer = {{ STATSD_BUFFER | default(50) }}
[service]
region = useast
max_log_size = 1048576
[roles_middleware]
path = /v2.0/log,/v3.0/logs
default_roles = {{ AUTHORIZED_ROLES | default('admin, domainuser, domainadmin, monasca-user') }}
agent_roles = {{ AGENT_AUTHORIZED_ROLES | default('monasca-agent') }}
[log_publisher]
topics = log
kafka_url = {{ KAFKA_URI | default('kafka:9092') }}
max_message_size = 1048576
[kafka_healthcheck]
kafka_url = {{ KAFKA_URI | default('kafka:9092') }}
kafka_topics = log
[keystone_authtoken]
auth_type = password
auth_url = {{ KEYSTONE_IDENTITY_URI }}
auth_uri = {{ KEYSTONE_AUTH_URI }}
username = {{ KEYSTONE_ADMIN_USER }}
password = {{ KEYSTONE_ADMIN_PASSWORD }}
user_domain_name = Default
project_name = {{ KEYSTONE_ADMIN_TENANT }}
project_domain_name = Default
service_token_roles_required = true
memcached_servers = {{ MEMCACHED_URI }}
insecure = false
cafile =
certfile =
keyfile =

View File

@ -1,46 +0,0 @@
#!/bin/sh
# 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.
# Starting script.
# All checks and configuration templating you need to do before service
# could be safely started should be added in this file.
set -eo pipefail # Exit the script if any statement returns error.
# Test services we need before starting our service.
echo "Start script: waiting for needed services"
python3 /kafka_wait_for_topics.py
# Template all config files before start, it will use env variables.
# Read usage examples: https://pypi.org/project/Templer/
echo "Start script: creating config files from templates"
templer -v -f /etc/monasca/monasca-log-api.conf.j2 /etc/monasca/monasca-log-api.conf
templer -v -f /etc/monasca/log-api-gunicorn.conf.j2 /etc/monasca/log-api-gunicorn.conf
templer -v -f /etc/monasca/log-api-logging.conf.j2 /etc/monasca/log-api-logging.conf
templer -v -f /etc/monasca/log-api-paste.ini.j2 /etc/monasca/log-api-paste.ini
# Start our service.
# gunicorn --args
echo "Start script: starting container"
gunicorn \
--config /etc/monasca/log-api-gunicorn.conf \
--paste /etc/monasca/log-api-paste.ini
# Allow server to stay alive in case of failure for 2 hours for debugging.
RESULT=$?
if [ $RESULT != 0 ] && [ "$STAY_ALIVE_ON_FAILURE" = "true" ]; then
echo "Service died, waiting 120 min before exiting"
sleep 7200
fi
exit $RESULT

View File

@ -1,142 +0,0 @@
# Monasca Log API - Kafka
Date: April 18, 2016
Document Version: v0.2
## Introduction
**monasca-log-api** uses kafka transport to ship received logs down to the
processing pipeline.
For more information about Kafka, please see [official documentation]
(http://kafka.apache.org/documentation.html).
## Output message format
Messages sent to kafka should have following format
(top level object is called **envelope**) and is combined out of three
elements:
* log
* creation_time
* meta
"log": <object>,
"creation_time": <number, timestamp>,
"meta": <object>
Log property should have at least following form:
"message": <string>,
"dimensions": <object>
Meta property should have following form:
"tenantId": <string>,
"region": <string>
Full example as json:
```json
{
"log": {
"message": "2015-11-13 12:44:42.411 27297 DEBUG kafka [-] Read 31/31 bytes from Kafka _read_bytes /opt/monasca/monasca-log-api/lib/python2.7/site-packages/kafka/conn.py:103",
"dimensions": {
"hostname": "devstack"
}
},
"creation_time": 1447834886,
"meta": {
"tenantId": "e4bd29509eda473092d32aadfee3e7b1",
"region": "pl"
}
}
```
### Fields explanation
* log - contains log specific information collected from the system. In the
most lean case that would be: **message**, **dimensions**
* message - normally that represent a single line from a log file
* dimensions - informations such as hostname where application is running
* creation_time - UNIX timestamp representing moment when log message was created
by monasca-log-api
* meta - contains tenantId and its region
**log** entry may of course contain many more fields that are considered valid
in given case. However two mentioned in this documentation are required.
All fields, apart from **creation_time** and **log**, are created from HTTP headers.
Description is available [here](/documentation/monasca-log-api-spec.md).
## Truncating too large message
Following section mostly applies to monasca-log-api v3.0
Each *envelope* sent to Kafka is serialized into JSON string. This string must
comply to Kafka limitation about [maximum message size](https://kafka.apache.org/08/configuration.html).
If JSON message is too big following actions are taken
1) difference between maximum allowed size and JSON message size (both in bytes).
```diff = (size(json_envelope) + size(envelope_key) + KAFKA_METADATA_SIZE) - maximum_allowed_size + TRUNCATION_SAFE_OFFSET```.
**KAFKA_METADATA_SIZE** is amount of bytes Kafka adds during transformation
of each message prior to sending it
2) log is enriched with property **truncated** set to **true** (```log['truncated'] = True```)
3) log's message is truncated by ```diff + TRUNCATED_PROPERTY_SIZE```.
**TRUNCATED_PROPERTY_SIZE** is the size of newly added property.
Variables explanation:
* **envelope_key** is the key used when routing logs into specific kafka partitions.
Its byte size is always fixed (determined from the byte size of timestamp represented as string).
```len(bytearray(str(int(time.time() * 1000)).encode('utf-8')))```
* **KAFKA_METADATA_SIZE** equals to 200 bytes.
* **TRUNCATION_SAFE_OFFSET** is equal to 1 ensuring that diff size will be always positive number
* **TRUNCATED_PROPERTY_SIZE** is calculated as byte size of expression ```log['truncated'] = True```
for each run of log-api.
## Configuration
### Java
Configuration for kafka should be placed in *.yml file and look similar to:
```yml
logTopic: logs
kafka:
brokerUris:
- localhost:8900
zookeeperUris:
- localhost:2181
healthCheckTopic: healthcheck
```
It is composed out of two relevant pieces
* logTopic - topic where data should be sent
* kafka - section containing information required to communicate in kafka.
For more details see [here](https://github.com/openstack/monasca-common/blob/master/java/monasca-common-kafka/src/main/java/monasca/common/messaging/kafka/KafkaConfiguration.java)
### Python
Configuration for kafka should be placed in *.conf file and look similar to:
```conf
[log_publisher]
topics = 'logs'
kafka_url = 'localhost:8900'
```
There are only two relevant options:
* topics - comma delimited list of topics where data should be sent
* kafka_url - address where kafka server is running
# Copyright 2016-2017 FUJITSU LIMITED
#
# 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.

View File

@ -1,108 +0,0 @@
# Monitoring for monasca-log-api
**monasca-log-api** can be monitored by examining following metrics
| Name | Meaning | Dimensions |
|-------------------------------------------|-------------------------|---------------|
| monasca.log.in_logs | Amount of received logs | version |
| monasca.log.in_logs_rejected | Amount of rejected logs (see below for details) | version |
| monasca.log.in_bulks_rejected | Amount of rejected bulks (see below for details) | version |
| monasca.log.in_logs_bytes | Size received logs (a.k.a. *Content-Length)* in bytes | version |
| monasca.log.out_logs | Amount of logs published to kafka | |
| monasca.log.out_logs_lost | Amount of logs lost during publish phase | |
| monasca.log.out_logs_truncated_bytes | Amount of truncated bytes, removed from message | |
| monasca.log.publish_time_ms | Time Log-Api needed to publish all logs to kafka | |
| monasca.log.processing_time_ms | Time Log-Api needed to process received logs. | version |
Additionally each metric contains following dimensions:
- **component** - monasca-log-api
- **service** - monitoring
## Metrics explained
### monasca.log.in_logs
Metric sent with amount of logs that were received by **Log-API**
and successfully passed initial validation. For **v2.0** this
metric will be always send with value one, for **v3.0** this metric's values
are equivalent to amount of element in bulk request.
### monasca.log.in_logs_rejected <a name="monasca_log_logs_rejected">
Logs can be rejected because of:
* checking content-type
* checking content-length
* reading payload
* retrieving logs from payload
* validating global dimensions (if set)(only valid for v3.0)
### monasca.log.in_bulks_rejected (only v3.0)
In **v2.0** bulk request is equivalent to single request (i.e. single-element bulk).
However in **v3.0** rejecting logs is done in two phases.
*Phase 1* is when there is no way to determine actual amount of logs
that were sent by client (see [monasca.log.in_logs_rejected](#monasca_log_logs_rejected))
If any of these steps was impossible to be executed entire bulk is
considered lost and thus all logs within.
If *Phase 1* passes, *Phase 2* is executed. At this point every
piece of data is available, however still some logs can be rejected,
because of:
* lack of certain fields (i.e. message)
* invalid local dimensions (if set)
In *Phase 2* metric [monasca.log.in_logs_rejected](#monasca_log_logs_rejected)
is produced.
### monasca.log.in_logs_bytes
Metric allows to track to size of requests API receives.
In **v3.0** To simplify implementation it is equivalent to **Content-Length** value.
However amount of global dimensions and other metadata when compared
to size of logs is negligible.
### monasca.log.out_logs
Amount of logs successfully published to kafka queue.
### monasca.log.out_logs_lost
Amount of logs that were not sent to kafka and **Log-API** was unable
to recover from error situation
### monasca.log.out_logs_truncated_bytes
Metric is sent with the amount of bytes that log's message is shorten
by if necessary. To read more about truncation see [here](/documentation/monasca-log-api-kafka.md).
If truncation did not happen, which should be normal situation for most
of the time, metric is updated with value **0**.
### monasca.log.publish_time_ms
Time that was needed to send all the logs into all the topics.
*monasca.log.processing_time_ms* includes value of that metric
within. It exists to see how much does publishing take in entire
processing.
### monasca.log.processing_time_ms
Total amount of time logs spent inside **Log-API**. Metric does not
include time needed to communicate with Keystone to authenticate request.
As far as possible it is meant to track **Log-API** itself
# Copyright 2016-2017 FUJITSU LIMITED
#
# 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.

View File

@ -1,319 +0,0 @@
# Monasca Log API
Date: May 27, 2016
Document Version: v2.2.2
# Logs
The logs resource allows logs to be created and queried.
## Create Logs
Create logs.
### POST /v3.0/logs
#### Headers
* X-Auth-Token (string, required) - Keystone auth token
* Content-Type (string, required) - application/json
#### Path Parameters
None.
#### Query Parameters
* tenant_id (string, optional, restricted) - Tenant ID (project ID) to create
log on behalf of. Usage of this query parameter requires the role specified
in the configuration option `delegate_roles` .
#### Request Body
JSON object which can have a maximum size of 5 MB. It consists of global
dimensions (optional) and array of logs. Each single log message with
resulting envelope can have a maximum size of 1 MB.
Dimensions is a dictionary of key-value pairs and should be consistent with
metric dimensions.
Logs is an array of JSON objects describing the log entries. Every log object
can have individual set of dimensions which has higher precedence than global
ones. It should be noted that dimensions presented in each log record are also
optional.
If both global (at the root level) and local (at log entry level)
dimensions would be present, they will be merged into one dictionary.
Please note that local dimensions are logically considered as more
specific thus in case of conflict (i.e. having two entries with the same
key in both global and local dimensions) local dimensions take
precedence over global dimensions.
#### Request Examples
POST logs
```
POST /v3.0/logs HTTP/1.1
Host: 192.168.10.4:5607
Content-Type: application/json
X-Auth-Token: 27feed73a0ce4138934e30d619b415b0
Cache-Control: no-cache
{
"dimensions":{
"hostname":"mini-mon",
"service":"monitoring"
},
"logs":[
{
"message":"msg1",
"dimensions":{
"component":"mysql",
"path":"/var/log/mysql.log"
}
},
{
"message":"msg2",
"dimensions":{
"component":"monasca-api",
"path":"/var/log/monasca/monasca-api.log"
}
}
]
}
```
### Response
#### Status Code
* 204 - No content
#### Response Body
This request does not return a response body.
## List logs
Get precise log listing filtered by dimensions.
Note that this API is in development, and is not currently implemented.
This interface can used to obtain log entries for a time range, based on
matching a set of exact dimension values. By default, entries will be returned
in descending timestamp order (newest first). The log entries returned by this
API will not necessarily be identical to those POST-ed to the service, as the
data returned will have been subjected to deployment-specific transformation
stages (i.e. the "monasca-log-transform" service).
### GET /v3.0/logs
#### Headers
* X-Auth-Token (string, required) - Keystone auth token
* Accept (string) - application/json
#### Path Parameters
None.
#### Query Parameters
* tenant_id (string, optional, restricted) - Tenant ID from which to get logs
from. This parameter can be used to get logs from a tenant other than the tenant
the request auth token is scoped to. Usage of this query parameter is restricted
to users with the monasca admin role, as defined in the monasca-log-api
configuration file, which defaults to `monasca-admin`.
* dimensions (string, optional) - A dictionary to filter logs by specified as a
comma separated array of (key, value) pairs as `key1:value1,key2:value2, ...`,
multiple values for a key may be specified as
`key1:value1|value2|...,key2:value4,...`. If the value is omitted in the form
`key1,key2, ...`, then entries are returned where the dimension exists with
any value.
* start_time (string, optional) - The start time in ISO 8601 combined date and
time format in UTC.
* end_time (string, optional) - The end time in ISO 8601 combined date and time
format in UTC.
* offset (integer, optional) - Number of log entries to skip (Default: 0).
* limit (integer, optional) - Limit number of logs returned (Default: 10).
* sort_by (string, optional) - Comma separated list of fields or dimensions to
sort by. Fields may be followed by 'asc' or 'desc' to set the direction, e.g.
'timestamp asc'. Allowed fields for sort_by are currently: 'timestamp'.
(Default: no sorting)
#### Request Body
None.
#### Request Examples
```
GET /v3.0/logs?dimensions=hostname:devstack&start_time=2015-03-00T00:00:01Z HTTP/1.1
Host: 192.168.10.4:5607
Content-Type: application/json
X-Auth-Token: 2b8882ba2ec44295bf300aecb2caa4f7
Cache-Control: no-cache
```
### Response
#### Status Code
* 200 - OK
#### Response Body
Returns a JSON object with a 'links' array of links and an 'elements' array of
log entry objects with the following fields:
* timestamp (timestamp) - The originating time in ISO 8601 combined date and
time format in UTC, with millisecond resolution if available.
* message (string) - The contents of the log message.
* dimensions ({string(255): string(255)}) - Dimensions of the log, either
supplied with the log or added by transformation.
#### Response Examples
```
{
"links": [
{
"rel": "prev",
"href": "http://192.168.10.4:5607/v3.0/logs?start_time=2015-03-00T00%3A00%3A00Z&dimensions=hostname%3Adevstack"
},
{
"rel": "self",
"href": "http://192.168.10.4:5607/v3.0/logs?offset=10&start_time=2015-03-00T00%3A00%3A00Z&dimensions=hostname%3Adevstack"
},
{
"rel": "next",
"href": "http://192.168.10.4:5607/v3.0/logs?offset=20&start_time=2015-03-00T00%3A00%3A00Z&dimensions=hostname%3Adevstack"
}
],
"elements": [
{
"timestamp":"2015-03-03T05:24:55.202Z",
"message":"msg1",
"dimensions":{
"hostname":"devstack",
"component":"mysql",
"path":"/var/log/mysql.log"
}
},
{
"timestamp":"2015-03-01T02:22:09.112Z",
"message":"msg2",
"dimensions":{
"hostname":"devstack",
"component":"monasca-api",
"path":"/var/log/monasca/monasca-api.log"
}
}
]
}
```
# Healthcheck
Note that following part is updated for Python implementation.
The *Monasca Log API* comes with a built-in health check mechanism.
It is available in two flavors, both accessible under ```/healthcheck```
endpoint.
## Complex check
The complex check not only returns a response with success code if *Monasca Log API*
is up and running but it also verifies if peripheral components, such as **Kafka**,
are healthy too.
*Monasca Log API* will respond with following codes:
* 200 - both API and external components are healthy.
* 503 - API is running but problems with peripheral components have been spotted.
Example:
```curl -XGET 192.168.10.4:5607/healthcheck```
### Peripheral checks
* **Kafka** is considered healthy if connection to broker can be established
and configured topics can be found.
## Simple check
The simple check only returns response only if *Monasca Log API* is up and running.
It does not return any data because it is accessible only for ```HEAD``` requests.
If the *Monasca Log API* is running the following response code: ```204``` is expected.
Example:
```curl -XHEAD 192.168.10.4:5607/healthcheck```
=======
### POST /v2.0/log/single (deprecated)
#### Headers
* X-Auth-Token (string, required) - Keystone auth token
* Content-Type (string, required) - application/json; text/plain
* X-Application-Type (string(255), optional) - Type of application
* X-Dimensions ({string(255):string(255)}, required) - A dictionary consisting of (key, value) pairs used to structure logs.
#### Path Parameters
None.
#### Request Body
Consists of a single plain text message or a JSON object which can have a maximum length of 1048576 characters.
#### Request Examples
##### Plain text log - single line
POST a single line of plain text log.
```
POST /v2.0/log/single HTTP/1.1
Host: 192.168.10.4:5607
Content-Type: text/plain
X-Auth-Token: 27feed73a0ce4138934e30d619b415b0
X-Application-Type: apache
X-Dimensions: applicationname:WebServer01,environment:production
Cache-Control: no-cache
Hello World
```
##### Plain text log - multi lines
POST a multiple lines of plain text log.
```
POST /v2.0/log/single HTTP/1.1
Host: 192.168.10.4:5607
Content-Type: text/plain
X-Auth-Token: 27feed73a0ce4138934e30d619b415b0
X-Application-Type: apache
X-Dimensions: applicationname:WebServer01,environment:production
Cache-Control: no-cache
Hello\nWorld
```
##### JSON log
POST a JSON log
```
POST /v2.0/log/single HTTP/1.1
Host: 192.168.10.4:5607
Content-Type: application/json
X-Auth-Token: 27feed73a0ce4138934e30d619b415b0
X-Application-Type: apache
X-Dimensions: applicationname:WebServer01,environment:production
Cache-Control: no-cache
{
"message":"Hello World!",
"from":"hoover"
}
```
### Response
#### Status Code
* 204 - No content
#### Response Body
This request does not return a response body.
# Copyright 2016-2017 FUJITSU LIMITED
#
# 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.

View File

@ -1,34 +0,0 @@
[loggers]
keys = root, kafka
[handlers]
keys = console, file
[formatters]
keys = context
[logger_root]
level = INFO
handlers = console, file
[logger_kafka]
qualname = kafka
level = INFO
handlers = console, file
propagate = 0
[handler_console]
class = logging.StreamHandler
args = (sys.stderr,)
level = DEBUG
formatter = context
[handler_file]
class = logging.handlers.RotatingFileHandler
level = DEBUG
formatter = context
# store up to 5*100MB of logs
args = ('/var/log/monasca/log-api.log', 'a', 104857600, 5)
[formatter_context]
class = oslo_log.formatters.ContextFormatter

View File

@ -1,78 +0,0 @@
#
# Copyright 2016-2017 FUJITSU LIMITED
#
# 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.
#
[DEFAULT]
name = main
[composite:main]
use = egg:Paste#urlmap
/: la_version
/healthcheck: la_healthcheck
/v2.0: la_api_v2
/v3.0: la_api_v3
[pipeline:la_version]
pipeline = error_trap versionapp
[pipeline:la_healthcheck]
pipeline = error_trap healthcheckapp
[pipeline:la_api_v2]
pipeline = error_trap request_id auth api_v2_app
[pipeline:la_api_v3]
pipeline = error_trap request_id auth api_v3_app
[app:versionapp]
paste.app_factory = monasca_log_api.app.api:create_version_app
[app:healthcheckapp]
paste.app_factory = monasca_log_api.app.api:create_healthcheck_app
[app:api_v2_app]
paste.app_factory = monasca_log_api.app.api:create_api_app
set api_version=v2.0
[app:api_v3_app]
paste.app_factory = monasca_log_api.app.api:create_api_app
set api_version=v3.0
[filter:auth]
paste.filter_factory = keystonemiddleware.auth_token:filter_factory
[filter:request_id]
paste.filter_factory = oslo_middleware.request_id:RequestId.factory
# NOTE(trebskit) this is optional
# insert this into either pipeline to get some WSGI environment debug output
[filter:debug]
paste.filter_factory = oslo_middleware.debug:Debug.factory
[filter:error_trap]
paste.filter_factory = oslo_middleware.catch_errors:CatchErrors.factory
[server:main]
use = egg:gunicorn#main
bind = 127.0.0.1:5607
workers = 9
worker-connections = 2000
worker-class = eventlet
timeout = 30
backlog = 2048
keepalive = 2
proc_name = monasca-log-api
loglevel = DEBUG

View File

@ -1,25 +0,0 @@
[uwsgi]
wsgi-file = /usr/local/bin/monasca-log-api-wsgi
# Versions of mod_proxy_uwsgi>=2.0.6 should use a UNIX socket, see
# http://uwsgi-docs.readthedocs.org/en/latest/Apache.html#mod-proxy-uwsgi
uwsgi-socket = 127.0.0.1:5607
# Override the default size for headers from the 4k default.
buffer-size = 65535
# This is running standalone
master = true
enable-threads = true
# Tune this to your environment.
processes = 4
# uwsgi recommends this to prevent thundering herd on accept.
thunder-lock = true
plugins = python
# This ensures that file descriptors aren't shared between keystone processes.
lazy-apps = true

View File

@ -1,87 +0,0 @@
alabaster==0.7.10
appdirs==1.3.0
Babel==2.3.4
bandit==1.1.0
bashate==0.5.1
chardet==3.0.4
configparser==3.5.0
coverage==4.0
debtcollector==1.2.0
doc8==0.6.0
docutils==0.11
dulwich==0.15.0
eventlet==0.18.2
extras==1.0.0
falcon==2.0.0
fixtures==3.0.0
future==0.16.0
gevent==1.2.2
gitdb==0.6.4
GitPython==1.0.1
greenlet==0.4.10
imagesize==0.7.1
iso8601==0.1.11
Jinja2==2.10
kazoo==2.2
keystoneauth1==3.4.0
keystonemiddleware==4.17.0
linecache2==1.0.0
MarkupSafe==1.0
mccabe==0.2.1
monasca-common==2.7.0
monasca-statsd==1.1.0
monotonic==0.6
mox3==0.20.0
msgpack-python==0.4.0
netaddr==0.7.18
netifaces==0.10.4
openstackdocstheme==2.2.1
os-api-ref==1.5.0
os-client-config==1.28.0
os-testr==1.0.0
oslo.config==5.2.0
oslo.context==2.19.2
oslo.i18n==3.15.3
oslo.log==3.36.0
oslo.middleware==3.31.0
oslo.policy==1.30.0
oslo.serialization==2.18.0
oslo.utils==3.33.0
oslotest==3.2.0
Paste==2.0.2
PasteDeploy==1.5.0
pbr==2.0.0
positional==1.2.1
pycadf==1.1.0
pyflakes==0.8.1
Pygments==2.2.0
pyinotify==0.9.6
PyMySQL==0.7.6
pyparsing==2.1.0
python-dateutil==2.5.3
python-keystoneclient==3.8.0
python-mimeparse==1.6.0
python-statsd==2.1.0
python-subunit==1.0.0
pytz==2013.6
PyYAML==3.12
reno==3.1.0
requests==2.14.2
requestsexceptions==1.2.0
restructuredtext-lint==1.1.1
rfc3986==0.3.1
simplejson==3.8.1
six==1.10.0
smmap==0.9.0
snowballstemmer==1.2.1
Sphinx==2.0.0
sphinxcontrib-websupport==1.0.1
statsd==3.2.1
stestr==1.0.0
stevedore==1.20.0
tabulate==0.8.1
testtools==2.2.0
traceback2==1.4.0
unittest2==1.1.0
WebOb==1.7.1
wrapt==1.7.0

View File

@ -1,129 +0,0 @@
# Copyright 2017 FUJITSU LIMITED
#
# 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.
"""
Module contains factories to initializes various applications
of monasca-log-api
"""
import six
import falcon
from oslo_log import log
from monasca_log_api.app.base import error_handlers
from monasca_log_api.app.base import request
from monasca_log_api.app.controller import healthchecks
from monasca_log_api.app.controller.v2 import logs as v2_logs
from monasca_log_api.app.controller.v3 import logs as v3_logs
from monasca_log_api.app.controller import versions
from monasca_log_api import config
def error_trap(app_name):
"""Decorator trapping any error during application boot time"""
@six.wraps(error_trap)
def _wrapper(func):
@six.wraps(_wrapper)
def _inner_wrapper(*args, **kwargs):
try:
return func(*args, **kwargs)
except Exception:
logger = log.getLogger(__name__)
logger.exception('Failed to load application \'%s\'', app_name)
raise
return _inner_wrapper
return _wrapper
def singleton_config(func):
"""Decorator ensuring that configuration is loaded only once."""
@six.wraps(singleton_config)
def _wrapper(global_config, **local_conf):
config.parse_args()
return func(global_config, **local_conf)
return _wrapper
@error_trap('version')
def create_version_app(global_conf, **local_conf):
"""Creates Version application"""
ctrl = versions.Versions()
controllers = {
'/': ctrl, # redirect http://host:port/ down to Version app
# avoid conflicts with actual pipelines and 404 error
'/version': ctrl, # list all the versions
'/version/{version_id}': ctrl # display details of the version
}
wsgi_app = falcon.API(
request_type=request.Request
)
wsgi_app.req_options.strip_url_path_trailing_slash = True
for route, ctrl in controllers.items():
wsgi_app.add_route(route, ctrl)
return wsgi_app
@error_trap('healthcheck')
def create_healthcheck_app(global_conf, **local_conf):
"""Creates Healthcheck application"""
ctrl = healthchecks.HealthChecks()
controllers = {
'/': ctrl
}
wsgi_app = falcon.API(
request_type=request.Request
)
for route, ctrl in controllers.items():
wsgi_app.add_route(route, ctrl)
return wsgi_app
@error_trap('api')
@singleton_config
def create_api_app(global_conf, **local_conf):
"""Creates MainAPI application"""
controllers = {}
api_version = global_conf.get('api_version')
if api_version == 'v2.0':
controllers.update({
'/log/single': v2_logs.Logs()
})
elif api_version == 'v3.0':
controllers.update({
'/logs': v3_logs.Logs()
})
wsgi_app = falcon.API(
request_type=request.Request
)
for route, ctrl in controllers.items():
wsgi_app.add_route(route, ctrl)
error_handlers.register_error_handlers(wsgi_app)
return wsgi_app

View File

@ -1,28 +0,0 @@
# Copyright 2016 FUJITSU LIMITED
#
# 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 falcon
from monasca_log_api.app.base import model
def log_envelope_exception_handler(ex, req, resp, params):
raise falcon.HTTPUnprocessableEntity(
title='Failed to create Envelope',
description=ex.message)
def register_error_handlers(app):
app.add_error_handler(model.LogEnvelopeException,
log_envelope_exception_handler)

View File

@ -1,38 +0,0 @@
# Copyright 2015 kornicameister@gmail.com
# Copyright 2015 FUJITSU LIMITED
#
# 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 falcon
HTTP_422 = '422 Unprocessable Entity'
class HTTPUnprocessableEntity(falcon.OptionalRepresentation, falcon.HTTPError):
"""HTTPUnprocessableEntity http error.
HTTPError that comes with '422 Unprocessable Entity' status
:argument: message(str) - meaningful description of what caused an error
:argument: kwargs - any other option defined in
:py:class:`falcon.OptionalRepresentation` and
:py:class:`falcon.HTTPError`
"""
def __init__(self, message, **kwargs):
falcon.HTTPError.__init__(self,
HTTP_422,
'unprocessable_entity',
message,
**kwargs
)

View File

@ -1,250 +0,0 @@
# Copyright 2015 kornicameister@gmail.com
# Copyright 2016-2017 FUJITSU LIMITED
#
# 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 time
import falcon
from monasca_common.kafka import producer
from monasca_log_api.common.rest import utils as rest_utils
from oslo_log import log
from oslo_utils import encodeutils
from monasca_log_api.app.base import model
from monasca_log_api import conf
from monasca_log_api.monitoring import client
from monasca_log_api.monitoring import metrics
LOG = log.getLogger(__name__)
CONF = conf.CONF
_RETRY_AFTER = 60
_TIMESTAMP_KEY_SIZE = len(
bytearray(str(int(time.time() * 1000)).encode('utf-8')))
_TRUNCATED_PROPERTY_SIZE = len(
bytearray('"truncated": true'.encode('utf-8')))
_KAFKA_META_DATA_SIZE = 32
_TRUNCATION_SAFE_OFFSET = 1
class InvalidMessageException(Exception):
pass
class LogPublisher(object):
"""Publishes log data to Kafka
LogPublisher is able to send single message to multiple configured topic.
It uses following configuration written in conf file ::
[log_publisher]
topics = 'logs'
kafka_url = 'localhost:8900'
Note:
Uses :py:class:`monasca_common.kafka.producer.KafkaProducer`
to ship logs to kafka. For more details
see `monasca_common`_ github repository.
.. _monasca_common: https://github.com/openstack/monasca-common
"""
def __init__(self):
self._topics = CONF.log_publisher.topics
self.max_message_size = CONF.log_publisher.max_message_size
self._kafka_publisher = producer.KafkaProducer(
url=CONF.log_publisher.kafka_url
)
if CONF.monitoring.enable:
self._statsd = client.get_client()
# setup counter, gauges etc
self._logs_published_counter = self._statsd.get_counter(
metrics.LOGS_PUBLISHED_METRIC
)
self._publish_time_ms = self._statsd.get_timer(
metrics.LOGS_PUBLISH_TIME_METRIC
)
self._logs_lost_counter = self._statsd.get_counter(
metrics.LOGS_PUBLISHED_LOST_METRIC
)
self._logs_truncated_gauge = self._statsd.get_gauge(
metrics.LOGS_TRUNCATED_METRIC
)
LOG.info('Initializing LogPublisher <%s>', self)
def send_message(self, messages):
"""Sends message to each configured topic.
Note:
Falsy messages (i.e. empty) are not shipped to kafka
See also
* :py:class:`monasca_log_api.common.model.Envelope`
* :py:meth:`._is_message_valid`
:param dict|list messages: instance (or instances) of log envelope
"""
if not messages:
return
if not isinstance(messages, list):
messages = [messages]
sent_counter = 0
num_of_msgs = len(messages)
LOG.debug('About to publish %d messages to %s topics',
num_of_msgs, self._topics)
try:
send_messages = []
for message in messages:
msg = self._transform_message(message)
send_messages.append(msg)
if CONF.monitoring.enable:
with self._publish_time_ms.time(name=None):
self._publish(send_messages)
else:
self._publish(send_messages)
sent_counter = len(send_messages)
except Exception as ex:
LOG.exception('Failure in publishing messages to kafka')
raise ex
finally:
self._after_publish(sent_counter, num_of_msgs)
def _transform_message(self, message):
"""Transforms message into JSON.
Method executes transformation operation for
single element. Operation is set of following
operations:
* checking if message is valid
(:py:func:`.LogPublisher._is_message_valid`)
* truncating message if necessary
(:py:func:`.LogPublisher._truncate`)
:param model.Envelope message: instance of message
:return: serialized message
:rtype: str
"""
if not self._is_message_valid(message):
raise InvalidMessageException()
truncated = self._truncate(message)
return encodeutils.safe_encode(truncated, incoming='utf-8')
def _truncate(self, envelope):
"""Truncates the message if needed.
Each message send to kafka is verified.
Method checks if message serialized to json
exceeds maximum allowed size that can be posted to kafka
queue. If so, method truncates message property of the log
by difference between message and allowed size.
:param Envelope envelope: original envelope
:return: serialized message
:rtype: str
"""
msg_str = model.serialize_envelope(envelope)
envelope_size = ((len(bytearray(msg_str, 'utf-8', 'replace')) +
_TIMESTAMP_KEY_SIZE +
_KAFKA_META_DATA_SIZE)
if msg_str is not None else -1)
diff_size = ((envelope_size - self.max_message_size) +
_TRUNCATION_SAFE_OFFSET)
if diff_size > 1:
truncated_by = diff_size + _TRUNCATED_PROPERTY_SIZE
LOG.warning(('Detected message that exceeds %d bytes,'
'message will be truncated by %d bytes'),
self.max_message_size,
truncated_by)
log_msg = envelope['log']['message']
truncated_log_msg = log_msg[:-truncated_by]
envelope['log']['truncated'] = True
envelope['log']['message'] = truncated_log_msg
if CONF.monitoring.enable:
self._logs_truncated_gauge.send(name=None, value=truncated_by)
msg_str = rest_utils.as_json(envelope)
else:
if CONF.monitoring.enable:
self._logs_truncated_gauge.send(name=None, value=0)
return msg_str
def _publish(self, messages):
"""Publishes messages to kafka.
:param list messages: list of messages
"""
num_of_msg = len(messages)
LOG.debug('Publishing %d messages', num_of_msg)
try:
for topic in self._topics:
self._kafka_publisher.publish(
topic,
messages
)
LOG.debug('Sent %d messages to topic %s', num_of_msg, topic)
except Exception as ex:
raise falcon.HTTPServiceUnavailable('Service unavailable',
str(ex), 60)
@staticmethod
def _is_message_valid(message):
"""Validates message before sending.
Methods checks if message is :py:class:`model.Envelope`.
By being instance of this class it is ensured that all required
keys are found and they will have their values.
"""
return message and isinstance(message, model.Envelope)
def _after_publish(self, send_count, to_send_count):
"""Executed after publishing to sent metrics.
:param int send_count: how many messages have been sent
:param int to_send_count: how many messages should be sent
"""
failed_to_send = to_send_count - send_count
if failed_to_send == 0:
LOG.debug('Successfully published all [%d] messages',
send_count)
else:
error_str = ('Failed to send all messages, %d '
'messages out of %d have not been published')
LOG.error(error_str, failed_to_send, to_send_count)
if CONF.monitoring.enable:
self._logs_published_counter.increment(value=send_count)
self._logs_lost_counter.increment(value=failed_to_send)

View File

@ -1,119 +0,0 @@
# Copyright 2016 FUJITSU LIMITED
#
# 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_utils import timeutils
import six
from monasca_log_api.common.rest import utils as rest_utils
def serialize_envelope(envelope):
"""Returns json representation of an envelope.
:return: json object of envelope
:rtype: six.text_type
"""
json = rest_utils.as_json(envelope, ensure_ascii=False)
if six.PY2:
raw = six.text_type(json.replace(r'\\', r'\\\\'), encoding='utf-8',
errors='replace')
else:
raw = json
return raw
class LogEnvelopeException(Exception):
pass
class Envelope(dict):
def __init__(self, log, meta):
if not log:
error_msg = 'Envelope cannot be created without log'
raise LogEnvelopeException(error_msg)
if 'tenantId' not in meta or not meta.get('tenantId'):
error_msg = 'Envelope cannot be created without tenant'
raise LogEnvelopeException(error_msg)
creation_time = self._get_creation_time()
super(Envelope, self).__init__(
log=log,
creation_time=creation_time,
meta=meta
)
@staticmethod
def _get_creation_time():
return timeutils.utcnow_ts()
@classmethod
def new_envelope(cls, log, tenant_id, region, dimensions=None):
"""Creates new log envelope
Log envelope is combined ouf of following properties
* log - dict
* creation_time - timestamp
* meta - meta block
Example output json would like this:
.. code-block:: json
{
"log": {
"message": "Some message",
"dimensions": {
"hostname": "devstack"
}
},
"creation_time": 1447834886,
"meta": {
"tenantId": "e4bd29509eda473092d32aadfee3e7b1",
"region": "pl"
}
}
:param dict log: original log element (containing message and other
params
:param str tenant_id: tenant id to be put in meta field
:param str region: region to be put in meta field
:param dict dimensions: additional dimensions to be appended to log
object dimensions
"""
if dimensions:
log['dimensions'].update(dimensions)
log_meta = {
'region': region,
'tenantId': tenant_id
}
return cls(log, log_meta)
@property
def log(self):
return self.get('log', None)
@property
def creation_time(self):
return self.get('creation_time', None)
@property
def meta(self):
return self.get('meta', None)

View File

@ -1,111 +0,0 @@
# Copyright 2016 FUJITSU LIMITED
#
# 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 falcon
from monasca_common.policy import policy_engine as policy
from monasca_log_api.app.base import request_context
from monasca_log_api.app.base import validation
from monasca_log_api import policies
policy.POLICIES = policies
_TENANT_ID_PARAM = 'tenant_id'
"""Name of the query-param pointing at project-id (tenant-id)"""
class Request(falcon.Request):
"""Variation of falcon.Request with context
Following class enhances :py:class:`falcon.Request` with
:py:class:`context.RequestContext`.
"""
def __init__(self, env, options=None):
super(Request, self).__init__(env, options)
self.context = request_context.RequestContext.from_environ(self.env)
def validate(self, content_types):
"""Performs common request validation
Validation checklist (in that order):
* :py:func:`validation.validate_content_type`
* :py:func:`validation.validate_payload_size`
* :py:func:`validation.validate_cross_tenant`
:param content_types: allowed content-types handler supports
:type content_types: list
:raises Exception: if any of the validation fails
"""
validation.validate_content_type(self, content_types)
validation.validate_payload_size(self)
validation.validate_cross_tenant(
tenant_id=self.project_id,
roles=self.roles,
cross_tenant_id=self.cross_project_id
)
@property
def project_id(self):
"""Returns project-id (tenant-id)
:return: project-id
:rtype: str
"""
return self.context.project_id
@property
def cross_project_id(self):
"""Returns project-id (tenant-id) found in query params.
This particular project-id is later on identified as
cross-project-id
:return: project-id
:rtype: str
"""
return self.get_param(_TENANT_ID_PARAM, required=False)
@property
def user_id(self):
"""Returns user-id
:return: user-id
:rtype: str
"""
return self.context.user
@property
def roles(self):
"""Returns roles associated with user
:return: user's roles
:rtype: list
"""
return self.context.roles
def can(self, action, target=None):
return self.context.can(action, target)
def __repr__(self):
return '%s, context=%s' % (self.path, self.context)

Some files were not shown because too many files have changed in this diff Show More