To assist with getting a working Metlog set up, metlog-py provides a Config module which will take declarative configuration info in either ini file or python dictionary format and use it to configure a MetlogClient instance. Even if you choose not to use these configuration helpers, this document provides a good overview of the configurable options provided by default by the MetlogClient client class.
The config module will accept configuration data either in ini format (as a text value or a stream input) or as a Python dictionary value. This document will first describe the supported ini file format, followed by the corresponding dictionary format to which the ini format is ultimately converted behind the scenes.
The primary MetlogClient configuration should be provided in a metlog section of the provided ini file text. (Note that the actual name of the section is passed in to the config parsing function, so it can be any legal ini file section name, but for illustration purposes these documents will assume that the section name is metlog.) A sample metlog section might look like this:
[metlog]
logger = myapp
severity = 4
disabled_timers = foo
bar
sender_class = metlog.senders.zmq.ZmqPubSender
sender_bindstrs = tcp://127.0.0.1:5565
sender_queue_length = 5000
global_disabled_decorators = incr_count
Of all of these settings, only sender_class is strictly required. A detailed description of each option follows:
In addition to the main metlog section, any other config sections that start with metlog_ (or whatever section name is specified) will be considered to be related to the metlog installation. Only specific variations of these are supported, however. The first of these is configuration for MetlogClient Filters. Here is an example of such a configuration:
[metlog_filter_sev_max]
provider = metlog.filters.severity_max_provider
severity = 4
[metlog_filter_type_whitelist]
provider = metlog.filters.type_whitelist_provider
types = timer
oldstyle
Each metlog_filter_* section must contain a provider entry, which is a dotted name specifying a filter provider function. The rest of the options in that section will be converted into configuration parameters. The provider function will be called and passed the configuration parameters, returning a filter function that will be added to the client’s filters. The filters will be applied in the order they are specified. In this case a “severity max” filter will be applied, so that only messages with a severity of 4 (i.e. “warning”) or lower will actually be passed in to the sender. Additionally a “type whitelist” will be applied, so that only messages of type “timer” and “oldstyle” will be delivered.
Metlog allows you to bind new extensions onto the client through a plugin mechanism.
Each plugin must have a configuration section name with a prefix of metlog_plugin_. Configuration is parsed into a dictionary, passed into a configurator and then the resulting plugin method is bound to the client.
Each configuration section for a plugin must contain at least one option with the name provider. This is a dotted name for a function which will be used to configure a plugin. The return value for the provider is a configured method which will then be bound into the Metlog client.
Each plugin extension method has a canonical name that is bound to the metlog client as a method name. The suffix that follows the metlog_plugin_ prefix is used only to distinguish logical sections for each plugin within the configuration file.
An example best demonstrates what can be expected. To load the dummy plugin, you need a metlog_plugin_dummy section as well as some configuration parameters. Here’s an example
[metlog_plugin_dummysection]
provider=metlog.tests.plugin.config_plugin
port=8080
host=localhost
Once you obtain a reference to a client, you can access the new method.
from metlog.holder import CLIENT_HOLDER
client = CLIENT_HOLDER.get_client('your_app_name')
client.dummy('some', 'ignored', 'arguments', 42)
When using the client_from_text_config or client_from_stream_config functions of the config module to parse an ini format configuration, metlog-py simply converts these values to a dictionary which is then passed to client_from_dict_config. If you choose to not use the specified ini format, you can parse configuration yourself and call client_from_dict_config directly. The configuration specified in the “ini format” section above would be converted to the following dictionary:
{'logger': 'myapp',
'severity': 4,
'disabled_timers': ['foo', 'bar'],
'sender': {'class': 'metlog.senders.zmq.ZmqPubSender',
'bindstrs': 'tcp://127.0.0.1:5565',
'queue_length': 5000,
},
'global': {'disabled_decorators': ['incr_count']},
'filters': [('metlog.filters.severity_max',
{'severity': 4},
),
('metlog.filters.type_whitelist',
{'types': ['timer', 'oldstyle']},
),
],
}
To manually load a Metlog client with plugins, the client_from_dict_config function allows you to pass in a list of plugin configurations using the plugins dict key, used in the same fashion as filters in the example directly above.
The configuration specified in the “plugins” section above would be converted into the following dictionary, where the key will be the name of the method bound to the client:
{'dummy': ('metlog.tests.plugin:config_plugin',
{'port': 8080,
'host': 'localhost'
},
)
}
You may find yourself with a metlog client which is not behaving in a manner that you expect. Metlog provides a deepcopy of the configuration that was used when the client was instantiated for debugging purposes.
The following code shows how you can verify that the configuration used is actually what you expect it to be
cfg = {'logger': 'addons-marketplace-dev',
'sender': {'class': 'metlog.senders.UdpSender',
'host': ['logstash1', 'logstash2'],
'port': '5566'}}
client = client_from_dict_config(cfg)
assert client._config == json.dumps(cfg)