The New Relic Log API lets you push logs from your applications into New Relic without relying on agents.

Let’s see it in action. Imagine you have a Python script that’s generating logs and you want to send them directly to New Relic.

import requests
import json
import time

# Replace with your actual New Relic license key
LICENSE_KEY = "YOUR_LICENSE_KEY"
# New Relic Ingest API endpoint for logs
INGEST_URL = "https://log-api.newrelic.com/log/v1"

def send_log_to_newrelic(message, attributes=None):
    if attributes is None:
        attributes = {}

    payload = {
        "logs": [
            {
                "message": message,
                "timestamp": int(time.time() * 1000), # Milliseconds since epoch
                "attributes": {
                    "host": "my-server-01",
                    "appName": "MyPythonApp",
                    "environment": "production",
                    **attributes # Merge custom attributes
                }
            }
        ]
    }

    headers = {
        "Content-Type": "application/json",
        "X-License-Key": LICENSE_KEY
    }

    try:
        response = requests.post(INGEST_URL, headers=headers, data=json.dumps(payload))
        response.raise_for_status() # Raise an exception for bad status codes
        print(f"Log sent successfully. Status: {response.status_code}")
    except requests.exceptions.RequestException as e:
        print(f"Error sending log: {e}")
        if response:
            print(f"Response body: {response.text}")

# Example usage
if __name__ == "__main__":
    send_log_to_newrelic("User 'alice' logged in successfully.")
    send_log_to_newrelic("Database query failed for user 'bob'.", {"userId": "bob", "errorType": "timeout"})
    send_log_to_newrelic("Application is starting up.", {"pid": 12345})

This script defines a function send_log_to_newrelic that constructs a JSON payload according to the Log API’s specification. It includes essential fields like message, timestamp, and attributes. The attributes field is where you can add contextual data like host, appName, environment, or custom fields like userId and errorType. The script then sends this payload via an HTTP POST request to the New Relic Ingest API endpoint, using your account’s license key for authentication.

The core problem this solves is getting logs from systems that don’t have a readily available New Relic agent or where direct agent integration is complex. Think about serverless functions, custom applications running on bare metal, or even logs generated by network devices. Instead of building complex forwarding mechanisms, you can have your application or a small utility directly push logs to New Relic.

Internally, New Relic receives this JSON payload, parses it, and indexes the message and all attributes as searchable fields. This means you can later query for logs based on any of the attributes you sent, such as appName: 'MyPythonApp' and environment: 'production'. The timestamp field is crucial for correlating these logs with other telemetry data like traces and metrics.

The attributes are the real power here. They aren’t just metadata; they become first-class citizens for querying. You can add arbitrary key-value pairs, and New Relic will index them. This allows for incredibly granular filtering and analysis. For instance, if you add a transactionId attribute to your logs, you can filter logs for a specific transaction to debug a particular request.

When you send multiple logs in a single request, as the API supports, you’re sending a JSON object where the top-level key is logs, and its value is an array of individual log entries. Each entry in the array is a distinct log event with its own message, timestamp, and attributes. This batching capability is key for efficiency, reducing network overhead and improving ingest performance compared to sending each log individually.

A common point of confusion is the timestamp format. It must be an integer representing milliseconds since the Unix epoch (January 1, 1970, 00:00:00 UTC). If you provide it in seconds or as a string, New Relic might misinterpret the time, leading to logs appearing out of order or at the wrong time in your New Relic dashboards.

The next concept you’ll likely explore is structured logging, where the message itself is a JSON string, allowing for even deeper, nested attributes within the log message.

Want structured learning?

Take the full Newrelic course →