SaneLog Documentation
Documentation Sending logs
Light mode
Dark mode
Match system
Log in Sign up
Light mode
Dark mode
Match system

Sending logs

Syslog and sender approval, the HTTP ingest endpoint, and config sets.

On this page

Syslog

Syslog is the simplest way to get a server's logs into SaneLog. Point the server's syslog daemon at your account's endpoint, and every line the daemon handles is sent to SaneLog.

Your endpoint

Open Sources > All sources in the sidebar. On a new account, a panel headed Syslog is off is at the top of the page. Choose Switch on syslog and the account is given a port of its own. After that, the callout at the top of the page shows the endpoint as Syslog endpoint: hostname:port. The port belongs to your account for as long as the account exists.

An account that only sends over HTTPS never needs a port, so this step can be skipped.

The one port accepts three transports:

Transport Encrypted Accepted
TLS over TCP Yes Always
Plain TCP No Only while Accept unencrypted syslog is on
UDP No Only while Accept unencrypted syslog is on

Accept unencrypted syslog is off for a new account, so the port accepts TLS only. An Account Admin can switch it on under Account > Settings (choose Edit). Leave it off unless every sender is on a private network you trust - plain syslog can be read by anyone on the network path.

While the setting is off, a plain TCP connection is closed as soon as it starts sending, and UDP datagrams are not received. The sender's own logs show the closed connection.

While the setting is on, the dashboard's Needs attention list shows Unencrypted beside any source that sent plain syslog in the last day, so you can find the senders still to move to TLS.

Sender configuration

Under the endpoint on the Sources page are ready-made rsyslog configurations, with your hostname and port already filled in:

  • rsyslog configuration (TLS), which needs rsyslog's GnuTLS driver (apt install rsyslog-gnutls on Debian and Ubuntu, dnf install rsyslog-gnutls on RHEL, Rocky and Fedora) and rsyslog 8.2108 or newer. The comments in the configuration say what to change for an older rsyslog.
  • rsyslog configuration (plain TCP, private networks), shown only while the account accepts unencrypted syslog.

Both configurations set the following:

  • Full hostnames. preserveFQDN="on" sends web-1.example.com rather than web-1, so two machines with the same short name stay separate sources. This is a global rsyslog setting, so local log files show the full hostname too.
  • A disk-assisted queue. While the connection is down, lines are queued and spill to disk (up to 100 MB), then sent when the connection returns. The queue is saved when rsyslog stops, so a restart of the sender keeps it.
  • Keepalives. A dead connection is noticed within about 90 seconds and the sender switches to the queue, instead of writing into a broken connection.
  • A reconnect every 5,000 messages. Each reconnect looks up the hostname again, so a change of address on the SaneLog side is picked up without restarting rsyslog.

Neither configuration raises rsyslog's message limit, because that setting only takes effect at the top of /etc/rsyslog.conf. rsyslog cuts any message longer than 8 KB without warning, which is shorter than many stack traces. To keep long messages whole, add global(maxMessageSize="64k") at the very top of /etc/rsyslog.conf, before any module(load=...) line, and restart rsyslog. SaneLog keeps up to 256 KB per message.

Other syslog daemons (syslog-ng, systemd-journald forwarding, network appliances) work too. Send RFC 5424 or RFC 3164 syslog to the same hostname and port, over TLS where the daemon supports it. The FAQ has a ready-made syslog-ng configuration and the settings for Windows servers.

How sources appear

A syslog sender becomes a source the first time one of its lines arrives, named after the hostname in the message. There is nothing to create beforehand. When the hostname contains an environment name (such as web-1.production.example.com), the source is tagged with that environment.

Two servers that report the same hostname become one source, and a server whose hostname changes appears as a new source. Merging duplicates covers both. Sources covers editing, pausing and deleting a source.

Approving senders

Anyone who learns your port could send lines to it, so a syslog sender needs your approval. Every line carries two identities - the hostname in the message and the address it came from. SaneLog asks you to approve or reject a sender when a new hostname first sends from an address that is not trusted, or when an approved source starts sending from an address that is not trusted.

A new hostname from a trusted address is approved as it appears, with no row to approve. Addresses become trusted when you approve a sender or add a Trusted sender rule, such as one for a NAT gateway (see Sender rules). When Approve new syslog sources automatically is switched on, every new hostname is approved as it appears, and only its address waits for approval.

Senders waiting for a decision are listed as red rows under Senders waiting for approval, at the top of the dashboard and above the sources list. A source's own page lists its rows under Waiting for approval. A red count also appears beside All sources under Sources in the sidebar. There are two kinds of row:

  • Unknown source - a hostname sending from an address that is not trusted yet. The sources list marks it Pending. Its lines are stored, but it is left out of filters, alerts and the all-sources view in the Log Explorer until you approve it. You can still select it by name in the Log Explorer.
  • New address - an approved source sending from an address that is not trusted yet, such as a server that came back with a different public address. The source keeps logging as before.

Nothing is lost while a row waits. Logs from an unapproved sender are kept for seven days (or for the account's retention period, if that is shorter), and approving the sender keeps them for your account's full retention period.

So that nobody misses a waiting sender, SaneLog emails the account contact email while any sender is waiting:

  • within 15 minutes of a new sender starting to wait, listing every waiting sender
  • once a day after that, while any sender is still waiting

Each email says when the first logs from each sender will be deleted, and the last email before a deletion says it will happen within a day. The emails stop once every sender is approved or rejected. Each email is recorded in the account's audit log. An Account Admin can change the contact email under Account > Settings.

Each row says what Approve and Reject will do, and both ask you to confirm.

Approve trusts the sender:

  • The address becomes trusted.
  • An unknown hostname becomes an approved source.
  • Any other pending hostname sending from the same address is approved too.

Reject blocks the sender:

  • The port drops every line from the address before reading it.
  • An unknown source is removed. Delete any logs stored from this source is ticked by default - untick it to leave the stored lines to expire after seven days.
  • An approved source keeps its stored logs and its other addresses.

A decision never overrides an existing sender rule:

  • Rejecting an unknown source never blocks an address that a rule trusts, so rejecting a hostname behind a shared gateway leaves the gateway trusted.
  • Approving an unknown source never trusts an address that a rule blocks.

While the account has as many sources as its plan includes, approving an unknown source is refused and the confirmation says why. Approving a New address row still trusts that address. A new hostname from a trusted address, or one that Approve new syslog sources automatically would approve, waits as an unknown source instead.

Only users with write access can approve or reject. A Read Only user can see the rows.

Up to 25 unknown sources can wait at once. Lines from further unknown hostnames are dropped until some are approved or rejected, and the row list shows how many lines were dropped in the last 24 hours.

A source added with Add source is approved when it is created. Its source token identifies it, so it never needs an address approved.

Sender rules

Every approval and rejection becomes a rule under Sources > Sender rules. Each rule has an Address (one address, or a range such as 192.168.0.0/24) and a Rule of Trusted or Denied. A rule can be edited or removed at any time.

You can also add a rule with Add sender rule. Trusting the address of a NAT gateway your servers share means every hostname behind it is approved as it appears, with no row to approve. Trusting an address or range also approves the pending sources already sending from it and keeps their stored logs for the full retention period. When the gateway's address changes, edit the rule's address and the new address is trusted at once.

Servers behind one NAT gateway, or on fixed addresses, need no attention after the first approval. A fleet of short-lived instances with changing public addresses does. For that case, an Account Admin can switch on Approve new syslog sources automatically under Account > Settings. Each new hostname is then approved as it appears, but its address is not trusted: each address still appears as a New address row, and logs from it are kept for seven days until the address is approved.

Removing a rule changes what happens to new lines only:

  • After a Trusted rule is removed, new hostnames from that address wait for approval again. Sources already approved stay approved.
  • After a Denied rule is removed, lines from that address are accepted again, and a hostname rejected earlier appears as an unknown source the next time it sends.

Where an address is registered

Beside every address - in the sender rules, in the Senders card on a source's page and in the rows under Senders waiting for approval - SaneLog shows the city and country the address is registered to, with the country's flag. This lets you check where a sender is before you approve it. The audit log shows the same beside the address of each entry.

  • A range wider than a /24 shows its country only.
  • A private address, or an IPv6 address, shows no location.

SaneLog includes GeoLite2 data created by MaxMind, available from maxmind.com.

What is stored

Each syslog line becomes an event with its severity level, its program (the syslog tag), its message, the time the sender wrote on it, and the address it came from.

The source's config set can also change how lines are stored - see Config sets. It can move JSON at the end of a message into attributes, restore line breaks, and merge stack-trace lines into the event that started them.

HTTP

Anything that can make an HTTPS request can send events to SaneLog: an application, a script, a cloud function or a cron job. Each request carries a source token, which identifies the source the events are stored under.

Getting a token

Choose Sources > All sources > Add source and save the form. The source's page then shows the token in its Source token card, along with a ready-to-run curl example, and the token can be copied from there at any time. An existing source's token is on the same card. Source tokens covers issuing, rotating and revoking a token.

Sending an event

curl -X POST https://app.sanelog.com/ingest \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"message": "hello sanelog", "level": "info", "program": "demo"}'

The body is one JSON object for a single event. To send several events in one request, send NDJSON: one JSON object per line. A body can be gzip-compressed if the request sets Content-Encoding: gzip.

Event fields

Field Required Meaning
message Yes The log line. An event without a message is rejected.
level No A syslog severity keyword: emerg, alert, crit, err, warning, notice, info or debug. Missing or any other value, the level is info.
program No What wrote the line - an application or component name.
dt or timestamp No When it happened, as an ISO 8601 date and time or Unix seconds. Missing or unreadable, the time of receipt is used.
attributes No An object of structured data to store with the event.

Without an attributes object, any other top-level keys are stored as attributes instead, so an application's own log shape usually works unchanged. When attributes is present, other top-level keys are ignored.

When the source's config set has Extract embedded JSON on, a message ending in a JSON object has that object moved into the attributes. This is how Laravel-style log lines arrive with their context intact.

Request size and rate

  • A request body can be up to 1 MB, or 5 MB once decompressed.
  • A request can carry up to 500 events. Lines after the 500th are rejected, and the first 500 are kept.
  • A message over 256 KB is cut to its first 256 KB and marked with a truncated attribute. The event is kept.
  • Attributes over 256 KB in total are dropped, and the event is kept and marked truncated.
  • An event keeps its first 100 attribute fields, and anything nested deeper than six levels is stored as JSON text. Either cut marks the event truncated.
  • Each token can make 600 requests a minute, and each sending address 1,200.

A malformed line in a batch never fails the batch. It is counted as rejected and the other lines are kept.

Responses

Status Meaning
204 Accepted. A batch partly over the flood limit or the free period's monthly allowance still returns 204 - the excess is dropped and counted, and the rest is kept.
400 Nothing in the body could be used, or a gzip body could not be decompressed.
401 The token is missing, unknown or revoked, or is an account API token rather than a source token.
402 No event in the batch was accepted because the account's free period has ended, or because the free period's monthly allowance is used up. The response body says which. Events are accepted again when the account moves to a paid plan, or, for a used-up allowance, when the next calendar month begins (UTC).
403 The source is paused.
413 The body is over 1 MB, or over 5 MB once decompressed.
429 Too many requests from this token or address, or every event in the batch was over the config set's flood limit.

AWS

SaneLog accepts two kinds of AWS data: log streams from CloudWatch Logs, forwarded by a small function deployed into your AWS account, and service events from EventBridge, delivered with no code. Both send with a source's token. The AWS section describes both setups step by step, in the AWS console or with the AWS CLI, and includes the forwarder's code.

Config sets

A config set is a group of settings for receiving logs, applied to a source: how many events to accept, and how to turn lines into events. Every source uses exactly one config set.

Config sets are managed under Sources > Config sets. To choose a source's config set, open the source, choose Edit and pick a Config set.

The account's Default set applies to every source that has not chosen another. It cannot be renamed or deleted. Add more sets with Add config set for sources that need different settings.

A new account's Default set starts with a flood limit of 5,000 events a minute, with Suppress blank messages, Extract embedded JSON and Decode control characters on, and Merge multi-line entries off. A new set starts with the same values.

A config set that any source uses cannot be deleted. Move those sources to another set first.

Which addresses may send at all is not part of a config set. That is decided per address by the sender rules.

Limits

Flood limit (events/min). The flood limit is the most events one source can send in a minute. Events over the flood limit are dropped and counted, so a runaway process cannot fill the account, and the source's page shows how many were dropped under Dropped events (last 24 hours). Each source using the set has its own flood limit. Leave the value empty for no flood limit.

Syslog and HTTP are counted separately, so a source that sends both ways can reach twice its flood limit.

The API and the MCP server report the same drops to a coding agent. An answer over a time window carries dropped: the number of events dropped inside that window, with the source, the reasons, the minutes it happened and the source's current flood limit. A count sitting at the flood limit is the limit, not the sender's rate. dropped is left out of an answer when the counts could not be read.

Suppress blank messages. Syslog events with an empty message are dropped and counted instead of stored. Over HTTP, an event with an empty message is always rejected.

Shaping lines into events

Extract embedded JSON. A message that ends in a JSON object (the Laravel log format, and many others) has the object moved into the event's attributes. The text before it stays as the message. Attributes are what field conditions in the Log Explorer and in filters check.

Decode control characters. rsyslog forwards a line break inside a message as the text #012 and a tab as #011. With this setting on, these are turned back into line breaks and tabs, so a multi-line message keeps its line breaks. Other escapes are kept as sent - the Log Explorer shows terminal color codes (#033[...) as colors.

Merge multi-line entries. Stack-trace continuation lines (PHP frames, Stack trace: lines, indented lines) are merged into the event that started them, so a trace is one event instead of fifty.

  • Over syslog, the last line before a pause waits about one second for a possible continuation before the event is stored.
  • Syslog removes the spaces at the start of a message, so indented continuation lines (Python and Java tracebacks) are recognised mainly over HTTP.
  • A merged event holds up to 500 lines or 256 KB. A continuation past that starts a new event, and nothing is dropped.

Counters

Everything a config set drops is counted by reason, and shown on the source's page under Dropped events (last 24 hours).

When a source has events dropped by its flood limit in the last hour, the dashboard lists it under Needs attention, with the count and a link to the config set. Suppressed blank messages appear on the source's page only, since they are dropped because the setting asks for it.