Skip to main content

Log Collection

SkySignal captures logs from your Meteor application automatically, giving you a centralized place to search, filter, and correlate log output with traces and errors.

What Gets Tracked

SkySignal intercepts logs from two sources:

Console methods - console.log, console.info, console.warn, console.error, and console.debug are all intercepted automatically. The original console output still works as normal; the agent just taps into it.

Meteor's Log package - If your app uses the logging package (most Meteor apps do), the agent also intercepts Log.info, Log.warn, Log.error, and Log.debug.

For each log entry, the agent captures:

FieldDescription
levelLog level (debug, info, warn, error, fatal)
messageThe log message content
timestampWhen the log was emitted
sourceWhere it came from: console, meteor-log, or api (manual submission)
metadataOptional structured data attached to the log

Automatic Method Context

When a log happens inside a running Meteor Method, the agent automatically attaches extra context:

FieldDescription
methodNameThe Method that was executing when the log was emitted
traceIdThe trace ID for that Method call
userIdThe user who called the Method
sessionIdThe DDP session ID

This means you can click through from a log entry to the full Method trace, or see all logs that happened during a specific Method call. No extra code required on your part.

Configuration

All log collection settings go in the skysignal block of your settings.json:

{
"skysignal": {
"collectLogs": true,
"logLevels": ["info", "warn", "error", "fatal"],
"logSampleRate": 1.0,
"logMaxMessageLength": 10000,
"logCaptureConsole": true,
"logCaptureMeteorLog": true
}
}
OptionTypeDefaultDescription
collectLogsBooleantrueMaster switch for log collection. Set to false to disable all log capture.
logLevelsArray["info", "warn", "error", "fatal"]Which log levels to capture. Levels not in this array are ignored.
logSampleRateNumber1.0Fraction of logs to capture, from 0.0 (none) to 1.0 (all).
logMaxMessageLengthNumber10000Maximum character length for log messages. Messages longer than this are truncated.
logCaptureConsoleBooleantrueWhether to intercept console.log/info/warn/error/debug.
logCaptureMeteorLogBooleantrueWhether to intercept Meteor's Log.info/warn/error/debug (requires the logging package).

Manual Log Submission

Sometimes you want to log a specific business event that you know you always want captured, regardless of sampling settings. Use SkySignalAgent.addLog() for this:

import { SkySignalAgent } from 'meteor/skysignal:agent';

SkySignalAgent.addLog('info', 'User signed up', { userId: 'abc123', plan: 'pro' });
SkySignalAgent.addLog('error', 'Payment failed', { orderId: 'xyz', provider: 'stripe' });

The signature is addLog(level, message, metadata). The metadata argument is optional and can be any plain object.

Logs submitted via addLog() are tagged with source "api" so you can distinguish them from automatically captured console/Meteor logs. They bypass logSampleRate -- manual logs are always captured (as long as collectLogs is true and the level is in logLevels).

Viewing Logs

Navigate to the Logs view in the sidebar to see your captured logs. From there you can:

  • Search by message text (full-text search across log messages)
  • Filter by level - Narrow down to just errors, warnings, etc.
  • Filter by time range - Focus on a specific window
  • Correlate with traces - Logs captured during a Method call link directly to the Method trace
  • Correlate with errors - If an error was thrown in the same Method execution, the log entry links to it

This correlation is what makes centralized logging useful compared to just grepping your server output. When a user reports a problem, you can find the error, see the trace, and read every log line that happened during that request.

Sampling

For high-traffic applications, capturing every single log can generate a lot of data. Use logSampleRate to reduce the volume:

{
"skysignal": {
"logSampleRate": 0.1
}
}

A value of 0.1 means roughly 10% of logs are captured. The sampling is random and applied per log entry.

A few things to keep in mind with sampling:

  • Errors and warnings are often more valuable than info/debug -- consider keeping logSampleRate at 1.0 and just removing "debug" and "info" from logLevels instead.
  • Manual logs via SkySignalAgent.addLog() are not affected by sampling. They always get through.
  • Sampling is applied on the agent side, before data is sent to SkySignal, so it does reduce network and storage overhead.

Best Practices

Use logLevels to control volume in production

If your app logs a lot of debug/info output, skip those levels in production rather than sampling them:

{
"skysignal": {
"logLevels": ["warn", "error", "fatal"]
}
}

This way you always capture every warning and error, but skip the noisy stuff.

Use logSampleRate for high-throughput apps

If even your warn/error volume is high (thousands per minute), bring the sample rate down to keep costs and storage manageable. Start with 0.5 and adjust from there.

Use SkySignalAgent.addLog() for important business events

Things like user signups, payment completions, subscription changes -- these are events you always want captured regardless of sampling. Use the manual API for them:

SkySignalAgent.addLog('info', 'Subscription upgraded', {
userId,
oldPlan: 'starter',
newPlan: 'pro',
});

Keep metadata objects small

The metadata object is serialized and sent over the wire to SkySignal. Don't attach large objects like full database documents or request bodies. Stick to IDs, short strings, and numbers.

// Good: small, useful metadata
SkySignalAgent.addLog('error', 'Order processing failed', {
orderId: order._id,
step: 'payment',
amount: order.total,
});

// Bad: huge metadata
SkySignalAgent.addLog('error', 'Order processing failed', {
order, // entire document
cart, // entire cart object
userProfile, // entire profile
});

Troubleshooting

Logs Not Appearing

  1. Verify collectLogs is true (or not set -- it defaults to true)
  2. Check that the log level is included in logLevels
  3. If logSampleRate is low, you may need to generate more logs before some get through
  4. Make sure logCaptureConsole and/or logCaptureMeteorLog are enabled for the source you expect

Logs Missing Method Context

Method context (methodName, traceId, etc.) is only attached when the log happens inside a Meteor Method execution context. Logs emitted from startup code, background jobs, or async callbacks that have left the Method fiber/async context will not have Method context attached.

Messages Are Truncated

If your log messages are being cut off, increase logMaxMessageLength. The default of 10,000 characters is generous for most use cases, but if you're logging large payloads you may need to bump it up.

Next Steps