-
Notifications
You must be signed in to change notification settings - Fork 7
3.8 Diagnostics
As messages are received and processed, Platibus emits DiagnosticEvents that provide visibility into the low level activity that takes place. Diagnostic events are raised via the IDiagnosticService. Implementers can consume these events by registering one or more IDiagnosticEventSink implementations with the IDiagnosticService
.
Diagnostic event sinks can be registered declaratively in the nested <diagnostics>
configuration element or by invoking the AddSink
method of the diagnostic service instance exposed through the DiagnosticService
property on the configuration object passed to a configuration hook.
The base diagnostic events specifies the following fields:
Field | Required | Description |
---|---|---|
Source | No | The object that raised the event |
Timestamp | Yes | The UTC timestamp indicating when the event was raised |
Type | Yes | The type of diagnostic event |
Detail | No | Specific details regarding this instance of the event |
Exception | No | The exception that prompted the event to be raised |
Message | No | The Platibus Message to which the event pertains |
Endpoint | No | The name of the endpoint to which the event pertains |
Queue | No | The name of the queue to which the event pertains |
Topic | No | The name of the topic to which the event pertains |
All diagnostic events are associated with a diagnostic event types. These types are discrete and there are a finite number specified within the core Platibus libraries, but they are also extensible. The diagnostic event type specifically and unambiguously the event that occurred. They are intended to be machine readable to enable intelligent grouping and windowing of events within sinks (e.g. for monitoring or metrics gathering).
The complete list of supported diagnostic event types can be found in the following classes:
- DiagnosticEventType
- FilesystemEventType
- HttpEventType
- SQLEventType
- MongoDBEventType
- RabbitMQEventType
Diagnostic event types are also associated with a diagnostic event level, which determines the severity or urgency of the event.
The diagnostic event levels specified by Platibus mirror those of many logging frameworks.
Level | Value | Description |
---|---|---|
Trace | -1 | Routine low-level events used for monitoring or metrics gathering |
Debug | 0 | Routine low-level events exposing intermediate state, branch logic, or other information useful for troubleshooting unexpected conditions or outcomes (default) |
Info | 1 | Routine high-level events used to verify correct operation |
Warn | 2 | Unexpected but recoverable conditions that may warrant attention |
Error | 3 | Unexpected and unrecoverable conditions that may require review and intervention |
The following sections describe the diagnostic event sink providers shipped with the Platibus
package.
All sinks can be wrapped in a filtering sink to limit the events that are passed through to sink.
Events can be filtered by diagnostic event level by specifying minLevel
and/or maxLevel
attributes in the declarative configuration for any sink:
<diagnostics>
<sinks>
<add name="consoleSink" provider="Console" minLevel="Warn" maxLevel="Error" />
</sinks>
</diagnostics>
Programmatic configuration example:
public class ConfigurationHook : IConfigurationHook
{
public void Configure(PlatibusConfiguration configuration)
{
var consoleSink = new ConsoleLoggingSink();
var minLevel = DiagnosticEventLevel.Warn;
var maxLevel = DiagnosticEventLevel.Error;
var filter = new DiagnosticEventLevelSpecification(minLevel, maxLevel);
var filteringSink = new FilteringSink(consoleSink, filter);
configuration.DiagnosticService.AddSink(filteringSink);
}
}
If programmatic configuration is used, then any implementation of IDiagnosticEventSpecification can be supplied as the second argument to FilteringSink.
The ConsoleLoggingSink emits formatted messages to the console.
Declarative configuration example:
<diagnostics>
<sinks>
<add name="consoleSink" provider="Console" />
</sinks>
</diagnostics>
Programmatic configuration example:
public class ConfigurationHook : IConfigurationHook
{
public void Configure(PlatibusConfiguration configuration)
{
var consoleSink = new ConsoleLoggingSink();
configuration.DiagnosticService.AddSink(consoleSink);
}
}
Platibus version 3 and prior uses Common Logging for all diagnostic output. The CommonLoggingSink has been provided to enable the use of existing logging configuration as much as possible.
Note: the log categories used by the CommonLoggingSink are based on the DiagnosticEventType and not the previously defined LoggingCategories. Adjustments to existing rules may be needed.
Declarative configuration example:
<diagnostics>
<sinks>
<add name="commonLoggingSink" provider="CommonLogging" />
</sinks>
</diagnostics>
Programmatic configuration example:
public class ConfigurationHook : IConfigurationHook
{
public void Configure(PlatibusConfiguration configuration)
{
var commonLoggingSink = new CommonLoggingSink();
configuration.DiagnosticService.AddSink(commonLoggingSink);
}
}
Platibus supports output of diagnostic events in Graylog Extended Logging Format (GELF) to UDP, TCP, or HTTP inputs in a Graylog server or compatible service.
The GelfUdpLoggingSink emits GELF formatted log events over UDP with optional compression.
Declarative configuration example:
<diagnostics>
<sinks>
<add name="gelfUdpSink" provider="GelfUdp"
host="127.0.0.1" port="12201" compress="true" />
</sinks>
</diagnostics>
Programmatic configuration example:
public class ConfigurationHook : IConfigurationHook
{
public void Configure(PlatibusConfiguration configuration)
{
var gelfUdpSink = new GelfUdpLoggingSink("127.0.0.1", "12201", true);
configuration.DiagnosticService.AddSink(gelfUdpSink);
}
}
The GelfTcpLoggingSink emits GELF formatted log events over a persistent TCP connection.
Declarative configuration example:
<diagnostics>
<sinks>
<add name="gelfTcpSink" provider="GelfTcp"
host="127.0.0.1" port="12201" />
</sinks>
</diagnostics>
Programmatic configuration example:
public class ConfigurationHook : IConfigurationHook
{
public void Configure(PlatibusConfiguration configuration)
{
var gelfTcpSink = new GelfTcpLoggingSink("127.0.0.1", "12201");
configuration.DiagnosticService.AddSink(gelfTcpSink);
}
}
The GelfHttpLoggingSink POSTs GELF formatted log events to an HTTP REST endpoint. Authentication is supported but optional.
Declarative configuration example:
<diagnostics>
<sinks>
<add name="gelfHttpSink" provider="GelfHttp"
uri="http://127.0.0.1:12201/gelf" username="user" password="pass" />
</sinks>
</diagnostics>
Programmatic configuration example:
public class ConfigurationHook : IConfigurationHook
{
public void Configure(PlatibusConfiguration configuration)
{
var uri = new Uri("http://localhost:12201/gelf");
var credentials = new BasicAuthCredentials("user", "pass");
var gelfHttpSink = new GelfHttpLoggingSink(uri, credentials);
configuration.DiagnosticService.AddSink(gelfHttpSink);
}
}
The InfluxDBSink counts the number of instances of certain types of diagnostic events and periodically POSTs points to an InfluxDB database. Implementers must specify the URI of the InfluxDB server and the database to which points are written. The name of the measurement, sample rate, precision, and custom tags are configurable but optional.
Implementers may specify a static dictionary of custom tags to include with each point. If custom tags are not specified, then the following tags will be included by default:
Key | Value |
---|---|
host | The hostname of the machine on which the application is running |
app | The name of the application approximated by the name of the entry or executing assembly |
app_ver | The version of the application approximated by the version number of the entry or executing assembly |
Field values are represented as long
integers that represent the number of occurrences between samples. The following fields are tracked:
Field | Value |
---|---|
requests | Total number of HTTP requests received |
received | Total number of messages received |
acknowledgements | Total number of messages acknowledged |
acknowledgement_failures | Total number of handling attempts in which messages were not acknowledged |
expired | Total number of expired messages |
dead | Total number of dead letters (maximum attempts exceeded) |
sent | Total number of messages sent |
delivered | Total number of sent messages that were successfully delivered |
delivery_failures | Total number of sent messages that could not be delivered |
errors | Total number of events with the Error level |
warnings | Total number of events with the Warning level |
Declarative configuration example:
<diagnostics>
<sinks>
<add name="influxDBSink" provider="InfluxDB"
uri="http://127.0.0.1:8086" database="mydb"
measurement="pb_stats" precision="s"
username="user" password="pass"
tags="host=myserver,app=MyApp,app_ver=1.2"
sampleRate="00:00:05"/>
</sinks>
</diagnostics>
Programmatic configuration example:
public class ConfigurationHook : IConfigurationHook
{
public void Configure(PlatibusConfiguration configuration)
{
var uri = new Uri("http://localhost:8086");
var database = "mydb";
var options = new InfluxDBOptions(uri, database)
{
Measurement = "pb_stats",
Username = "user",
Password = "pass",
Precision = InfluxDBPrecision.Second,
Tags = {
{"host", Environment.MachineName},
{"app", "MyApp"},
{"app_ver", "1.2"}
}
};
var sampleRate = TimeSpan.FromSeconds(5);
var influxDbSink = new InfluxDBSink(options, sampleRate);
configuration.DiagnosticService.AddSink(influxDbSink);
}
}