Make Your Logs Work for You

The days of logging in to servers and manually viewing log files are over. SolarWinds® Papertrail™ aggregates logs from applications, devices, and platforms to a central location.

View Technology Info

FEATURED TECHNOLOGY

Troubleshoot Fast and Enjoy It

SolarWinds® Papertrail™ provides cloud-based log management that seamlessly aggregates logs from applications, servers, network devices, services, platforms, and much more.

View Capabilities Info

FEATURED CAPABILITIES

Aggregate and Search Any Log

SolarWinds® Papertrail™ provides lightning-fast search, live tail, flexible system groups, team-wide access, and integration with popular communications platforms like PagerDuty and Slack to help you quickly track down customer problems, debug app requests, or troubleshoot slow database queries.

View Languages Info

FEATURED LANGUAGES

TBD - APM Integration Title

TBD - APM Integration Description

TBD Link

APM Integration Feature List

TBD - Built for Collaboration Title

TBD - Built for Collaboration Description

TBD Link

Built for Collaboration Feature List

Join SolarWinds Day October 19 to see the next evolution in observability. Register now.

Collect Logs: Apps & Services > Python

Python

Papertrail can accept logs from any Python app, including Django.

For accounts created via the Papertrail website, see methods A & B. For Heroku add-on accounts, see the Heroku section below.

Send log file with remote_syslog2

Configure your Python app to log to a file, then transmit the log file to Papertrail using remote_syslog2. This typically does not require any modifications to the app.

Send events using Python’s SysLogHandler

Python can also send log messages directly to Papertrail with Python’s SysLogHandler logging handler.

Older minor versions of Python 2.7 and 3.2 may be subject to this bug. The fix is present in current 2.7 and 3.2 as well as all versions of 3.3 and later.

Configuration

Examples

Django

Building on this example, add a new handler:

'handlers': {
    'SysLog': {
        'level': 'DEBUG',
        'class': 'logging.handlers.SysLogHandler',
        'formatter': 'simple',
        'address': ('logsN.papertrailapp.com', XXXXX)
    },
    ...
}

Change the address argument to match your Papertrail log destination.

To set the sender and program name, modify the simple formatter like so:

'formatters': {
    'simple': {
        'format': '%(asctime)s SENDER_NAME PROGRAM_NAME: %(message)s',
        'datefmt': '%Y-%m-%dT%H:%M:%S',
    },
    ...
}

Then add the new logging handler to at least one of the loggers in the config, for example:

'loggers': {
    'django': {
        'handlers': ['file', 'SysLog'],
        'level': 'INFO',
        'propagate': True,
    },
    ...
}

Generic Python app

import logging
import socket
from logging.handlers import SysLogHandler
class ContextFilter(logging.Filter):
    hostname = socket.gethostname()
    def filter(self, record):
        record.hostname = ContextFilter.hostname
        return True
syslog = SysLogHandler(address=('logsN.papertrailapp.com', XXXXX))
syslog.addFilter(ContextFilter())
format = '%(asctime)s %(hostname)s YOUR_APP: %(message)s'
formatter = logging.Formatter(format, datefmt='%b %d %H:%M:%S')
syslog.setFormatter(formatter)
logger = logging.getLogger()
logger.addHandler(syslog)
logger.setLevel(logging.INFO)
logger.info("This is a message")

Change the address argument to match your Papertrail account.

Format specifiers

These format specifiers have not been extensively tested but may be helpful as starting points, especially combined with the logging format specifiers.

A valid syslog message looks like this:

<22>Jan 2 23:34:45 hostname app_name[PID]: message

The timestamp can also be in other formats as shown in the code snippet above.

Here’s an example format specifier for having Python’s SysLogHandler generate syslog or syslog-like messages:

logging.Formatter('%(asctime)s %(hostname)s APP: %(message)s', datefmt='%b %d %H:%M:%S')

The system hostname can be obtained with socket.gethostname(), by honoring the HOSTNAME environment variable with os.getenv('HOSTNAME'), or hardcoded as a static string literal. SysLogHandler automatically prefixes the message with a priority code, which is <22> in the example syslog message shown above.

Here’s an alternative example that may be useful, depending on your environment:

%(name)s[%(process)d]: %(levelname)s %(message)s

The DatagramHandler may be used to similar effect.

Multiline log Messages

Syslog is a simple protocol that transports single lines of text. As a result, no encoding is provided for newlines. The message has to be split and separate packets have to go out over the wire.

For example, to log an exception, you’d use something like:

tb = ""
try:
    a = 1/0
except:
    tb = traceback.format_exc()
lines = tb.split('\n')
for l in lines:
    logger.info(l)

Logging via the Heroku add-on

Rather than logging directly to syslog, send everything to the console and Heroku will forward it over to Papertrail.

The following handler will allow logging to the console:

import sys
LOGGING = {
    'handlers': {
        'console':{
            'level':'INFO',
            'class':'logging.StreamHandler',
            'strm': sys.stdout
        },
        ...
    }
}

Replace strm with stream if you’re using python 2.7.

The scripts are not supported under any SolarWinds support program or service. The scripts are provided AS IS without warranty of any kind. SolarWinds further disclaims all warranties including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose. The risk arising out of the use or performance of the scripts and documentation stays with you. In no event shall SolarWinds or anyone else involved in the creation, production, or delivery of the scripts be liable for any damages whatsoever (including, without limitation, damages for loss of business profits, business interruption, loss of business information, or other pecuniary loss) arising out of the use of or inability to use the scripts or documentation.