Atomia Performance Monitoring

Logging of calls

35 views 0

Overview

Role of Performance Logging Component is data collecting. It is achieved through logging of calls. Call can be method/function call, http request, api call, database call, etc. It can be grouped into hierarchical, parent-child structure (call graph or call tree) where parent contains all invoked subcalls. Component can be used to track both outer application calls as well as inner ones.

Properties of Call

PROPERTY NAME DESCRIPTION
Application Name of the application where event occured
CallId call identifier (globaly unique)
CallName method name, request, function, stored procedure, etc
CallType http request, external api call, api invocation, database call, etc.
Duration duration of the call
StartTime date and time when the call started
RequestId Id of the top-level call, initiated by end user (usually a http request)
CallerId CallId which invoked current this call
SessionId End user’s SessionId (if exists)
Identity Current call identity
IP IP address or host name of invoker
Host Hostname of the machine which executes current application

For logging of inner calls Atomia.Provisioning.Diagnostic library is used. It provides simple and efficient classes for logging method execution time. Drawback is that existing code must be altered in order to log those calls.

Outer application calls can be logged without altering existing code. This is possible due to the fact that majority of Atomia applications uses .NET and IIS server as a platform. More sprecificaly, WCF is used as a service layer, and ASP.NET as a web application container. For data layer NHibernate OR/M is usually used. ASP.NET allows pluging a custom Http Module into http request pipeline by implementing IHttpModule interface and adding implementation class to pipeline through configuration file. WCF on the other hand also has interfaces for intercepting communication messages, both on a client and a server side. NHibernate also provides events which can be utilized to track database calls. Complete list of interfaces which must be implemented is shown in table below.

Interfaces

INTERFACE NAME DESCRIPTION
IHttpModule Used for intercepting http request/response in web applications
IClientMessageInspector Intercepts external API calls from WCF client (proxy class)
BehaviorExtensionElement, IEndpointBehavior Used for instantiating IClientMessageInspectorimplementation class
IDispatchMessageInspector Intercepts incoming WCF calls
BehaviorExtensionElement, IServiceBehavior Used for instantiating IDispatchMessageInspectorimplementation class
SoapExtension Intercepts calls in ASP.NET .asmx style web services
IPreLoadEventListener, IPreInsertEventListener, ... Intercepts database calls made by NHibernate layer

Table: Interfaces used for interception of outer application calls.

Logging of calls

It is important that each outer call in a pipeline has some common identifier which can identify initial call and group all subcalls. Further more, except for initial call (e.g. http request), all other outer calls must have some CallerID (in order to identify order of calls). This is done by passing identifiers through application and between applications. Inside of an application it can be achieved by using some implementation of Execution Context and outside it is implemented by storing identifer in a headers which are passed between applications. This way, it is possible to reconstruct calls throughout multiple application tiers.

Most of the interfaces used for call interception has defined at least two methods: one is intercepting call start, the other call end. Each method logs one performance event, and duration of call is calculated by subracting starting timestamp from the ending one.

Call identifiers

Image: Call identifiers.

Logging of calls must have minimal drawback on overall application performance. For logging of calls memory buffer should be used, and its size would have to be configurable. Memory buffer should write to some IPerformanceLogWriter interface so that log destination could be easisly changed (that way concrete implementations that write to local filesystem, database, service, etc. can be easily implemented). Also, to reduce performance effect on application, actual writing should be performed asynchronously.

Configuration

Configuration options for call filtering must also be implemented. User of Performance Logging component should have possibility to choose which calls are logged, and which are not. That way, some unneccessary call logs can be avoided (e.g. *.jpg, *.png, *.css etc) or only specific calls can be logged (e.g. some specific API method).

Optional request:

  • logging only some percentage of all calls
  • logging request of specific users
  • logging request in specific time periods
  • logging of intercepted messages or at least message sizes

Was this helpful?