Log::Log4perl::Appender::Raven - Append log events to your Sentry account.



This appender will send ALL the log events it receives to your Sentry DSN synchronously. If you generate a lot of logging, that can make your sentry account saturate quite quickly and your application come to a severe slowdown.

Using Log4perl appender's Threshold or Log::Log4perl::Filter in your log4perl config, and experimenting a little bit is Highly Recommended.

Remember sentry is designed to record errors, so hopefully your application will not generate too many of them.

You have been warned.


Read the CONFIGURATION section, then use Log4perl just as usual.

If you are not familiar with Log::Log4perl, please check Log::Log4perl

In a nutshell, here's the minimul l4p config to output anything from ERROR to Sentry:

  log4perl.rootLogger=DEBUG, Raven

  log4perl.appender.Raven.layout.ConversionPattern=%X{chunk} %d %F{1} %L> %m %n


This is just another Log::Log4perl::Appender.

Simple Configuration

The only mandatory configuration key is *sentry_dsn* which is your sentry dsn string obtained from your sentry account. See and for more details.

Alternatively to setting this configuration key, you can set an environment variable SENTRY_DSN with the same setting. - Not recommended -


  log4perl.rootLogger=ERROR, Raven

  layout_pattern=%X{chunk} %d %F{1} %L> %m %n


Configuring the culprit string

By default, this appender will calculate the Sentry culprit to be the fully qualified name of the function that called the log method, as Sentry recommends.

If you require more flexibility and precision in your culprit, you can configure it as a template. For instance:


The default is '{$function}', as Sentry prescribes. But most people will probably be more happy with the added {$line} element, as it makes discriminating between culprits easier.

The template format follows Text::Template and the available variables and functions are as follow:


The fully qualified name of the function that called the log method.


The line at which the log method was called


The Log4perl generated message. Keep in mind that this is the message AFTER it has been calculated by the layout pattern.

sign($string, $offset, $length)

A function that calculates a small (4 chars) signature of the given string. $string, $offset and $length are optional.

This is useful for instance if some part of your code manage errors in a centralized way, or in other terms if the place at which you call '$log->error()' can output various messages. To help discriminating between culprit, you can for instance configure your culprit template:

  log4perl.appender.Raven.sentry_culprit_template={$function}-{$line}-{sign($message, 30, 4)}

Note that in the example, we look at a part of the message after the 30th character, which helps skipping the common message parts defined by your message layout. Adjust this number (30) to make sure you pick a substring of your message in a meaningful area.


The default timeout is 1 second. Feel free to bump it up. If sending an event timesout (or if the sentry host is down or doesn't exist), a plain Perl warning will be output.

Configuration with Static Tags

You have the option of predefining a set of tags that will be send to your Sentry installation with every event. Remember Sentry tags have a name and a value (they are not just 'labels').



Configure and use Dynamic Tagging

Dynamic tagging is performed using the Log4Perl MDC mechanism. See Log::Log4perl::MDC if you are not familiar with it.

Anywhere in your code.

  Log::Log4perl::MDC->set('sentry_tags' , { subsystem => 'my_subsystem', ... });
  $log->error("Something very wrong");

Or specify which key to capture in config:


Note that tags added this way will be added to the statically define ones, or override them in case of conflict.

Note: Tags are meant to categorize your Sentry events and will be displayed in the Sentry GUI like any other category.

Configure and use User Data

Sentry supports structured user data that can be added to your event. User data works a bit like the tags, except only three keys are supported:

id, username and email. See Sentry::Raven (capture_user) for a description of those keys.

In your code:

  Log::Log4perl::MDC->set('sentry_user' , { id => '123' , email => '', username => 'jeteve' });
  $log->error("Something very wrong");

Or specify the MDC key to capture in Config:


Configure and use HTTP Request data.

Sentry support HTTP Request structured data that can be added to your event. HTTP Data work a bit like tags, except only a number of keys are supported:

url, method, data, query_string, cookies, headers, env

See Sentry::Raven (capture_request) or interface 'Http' in for a full description of those keys.

In your code:

  Log::Log4perl::MDC->set('sentry_http' , { url => '' , method => 'GET' , ... });
  $log->error("Something very wrong");

Or specify the MDC key to capture in Config:


Configure and use Dynamic Extra

Sentry allows you to specify any data (as a Single level HashRef) that will be stored with the Event.

It's very similar to dynamic tags, except its not tags.

Then anywere in your code:

  Log::Log4perl::MDC->set('my_sentry_extra' , { session_id => ... , ...  });
  $log->error("Something very wrong");

Or specify MDC key to capture in config:


Configuration with a Static Context.

You can use lines like:


To define static Sentry::Raven context. The list of context keys supported is not very long, and most of them are defined dynamically when you use this package anyway.

See Sentry::Raven for more details.

USING Log::Any

This is tested to work with Log::Any just the same way it works when you use Log4perl directly.


Warning: Experimental feature.

If your code, or some of its dependencies is not using Log4perl, you might want to consider infecting the __DIE__ pseudo signal with some amount of trickery to have die (and Carp::confess/croak) calls go through log4perl.

This appender makes that easy for you, and provides the 'infect_die' configuration property to do so:


This is heavily inspired by

While this can be convenient to quickly implement this in a non-log4perl aware piece of software, you are strongly encourage not to use this feature and pepper your call with appropriate Log4perl calls.


Sentry::Raven , Log::Log4perl, Log::Any , Log::Any::Adapter::Log4perl


Jerome Eteve