seqcli
repository·dev·Indexed 41 days ago
https://github.com/datalust/seqcliThe Seq command-line client for administering, logging, ingesting, and searching Seq from any OS. It provides a comprehensive interface for managing alerts, API keys, .NET [SeqApp] plug-ins, and server settings, and includes support for AI agents via skills and the Model Context Protocol (MCP).
What's inside seqcli
- SeqCli.Templates is a JSON-based templating system designed to facilitate the import of sets of related entities into a Seq server. It uses a JSON superset syntax that allows for JavaScript-style function calls to resolve relationships between entities during the import process.
Use Seq.Syntax for customizable app templates
devApps that support user-customizable output should use the
Seq.Syntaxtemplate language. Templates are compiled intoExpressionTemplateinstances and rendered against aLogEvent.Template Compilation
Compile templates in
OnAttached()or a factory constructor using anOrderedNameResolverto provide access to built-in functions and custom app properties.Custom Encoding
If your output format requires escaping (like HTML), implement
TemplateOutputEncoder. Note that the encoder is applied only to interpolated values, not to the literal template text.Built-in Functions and Name Resolution
You can expose custom functions and properties (like
@Hostor@App) to templates by implementing aNameResolverthat maps these tokens to your app's instances.// Template compilation using Seq.Syntax.Templates; using Seq.Syntax.Templates.Encoding; var template = new ExpressionTemplate( templateText, nameResolver: new OrderedNameResolver(new NameResolver[] { new StaticMemberNameResolver(typeof(MyBuiltInFunctions)), myAppNameResolver }), encoder: isPlainText ? null : new MyHtmlEncoder()); // Template rendering static string Format(ExpressionTemplate template, LogEvent evt) { var writer = new StringWriter(); template.Format(evt, writer); return writer.ToString(); } // Custom encoding class TemplateOutputTelegramHtmlEncoder : TemplateOutputEncoder { public override string Encode(string value) { return value .Replace("&", "&") .Replace("<", "<") .Replace(">", ">"); } }Template syntax for SeqCli.Templates
devThe templating language is a superset of JSON. It allows you to use JavaScript-style function calls within JSON values to dynamically resolve data. This is particularly useful for linking entities (like signals or users) that are being imported in the same batch.
Supported functions:
ref(filename): Resolves to the unique ID of the entity produced by importing the specifiedfilenameinto the target Seq instance. This allows you to create references to other entities defined within your template set.
{ "Title": "Web", "SignalId": ref("signal-HTTP Requests.json") }Use the store-and-forward ingestion proxy
devThe
seqcli forwardercommands provide a durable ingestion buffer for systems with intermittent connectivity. The forwarder implements the Seq ingestion API, allowing applications to write directly to the forwarder, which persists data locally until it can be successfully sent to the destination Seq server.Security Note: The forwarder HTTP API does not authenticate incoming requests by default. It is designed for local use in isolated environments (e.g., firewalled machines or secured container networks). If you enable additional APIs like the ingestion log, ensure they are not reachable externally.
# Start a forwarder listening on port 5341 and forwarding to a remote Seq server seqcli forwarder run --listen http://127.0.0.1:5341 -s https://seq.example.comHow routing and controllers function in the simulation
devThe
Routeris the final stage of the middleware chain. It inspects theHttpRequestpath and dispatches it to the appropriate action method on aControllersubclass.Routing Details:
- Route Templates: Supports a simple
{id}wildcard substitution. Note that the{id}value is not currently extracted or passed to the controller after selection. - Log Context: The router pushes
ControllerandActionproperties onto the log context to provide traceability for downstream operations (like database calls). - Action Methods: Must be decorated with the
[Route]attribute, be asynchronous, accept anHttpRequest, and return anHttpResponse.
- Route Templates: Supports a simple
Workflow for querying Seq metrics
devSeq stores OpenTelemetry metric samples in the
seriesdata source (a columnar store). To query metrics correctly and avoid performance issues or inaccurate data, you must follow this strict workflow:- Search for metric definitions: Use dedicated tools to find metric names and descriptions.
- Identify the metric kind: Determine if the metric is a
Sum,Gauge,Fixed, orExponentialtype. - List dimensions: Use
seqcli metrics dimensionsto find which dimensions apply to the metric. - List dimension values (Optional): Use
seqcli metrics dimensionvaluesto find specific values (e.g., service names) within those dimensions. - Run aggregate queries: Execute queries against the
seriesdata source using the discovered names, kinds, and dimensions.
Critical Constraints
- NEVER query the
seriesdata source directly for metric definitions or available dimensions. - NEVER use
distinctto list dimension values; use the dedicated dimension value tools instead. - NEVER evaluate projection queries against the
seriesdata source, as this impacts Seq performance. - ALWAYS include
where Has(<metric name>)in aggregate queries to avoid row count skew.
How metrics are collected and emitted in Roastery
devMetrics in this simulation do not use standard .NET
System.Diagnosticsor OpenTelemetry. Instead, they use plain dictionaries keyed by record structs, allowing for high-cardinality attributes (likeRoastId) without pre-registration.Metric Types and Behavior:
- Counters and Histograms: Use delta temporality. Samples accumulate in a
Sampleinstance, which is atomically swapped every five seconds and converted intoMetrics sampledlog events. - Gauges: Represent instantaneous last-write-wins values within a sampling interval.
Infrastructure:
RoasteryMetrics<TSample>: The base class providing collection infrastructure.RoasteryMetricsSample: Converts samples into log events.RoasteryWebMetrics: Handles web frontend metrics (e.g., HTTP durations, order counters).RoasteryProductionMetrics: Handles roasting and ambient environment metrics.
- Counters and Histograms: Use delta temporality. Samples accumulate in a
Understand the Seq Event Data Model
devAll events in Seq follow a unified data model. Spans are specifically identified by the presence of the
@Startproperty.Built-in Properties
Property Type Description @ArrivednumberArrival order relative to other events in the same batch. @DataobjectCompact internal representation. Avoid using this due to high runtime cost. @Elapsednumber?Duration of a span (in 100ns ticks). Only present on spans. @EventTypenumberNumeric hash of the @MessageTemplate.@Exceptionstring?The exception string (type, message, stack trace). @IdstringUnique event ID. @LevelstringSeverity (e.g., 'Error','ERROR') or span completion status.@MessagestringHuman-readable text or the span name. @MessageTemplatestringThe message template (messagetemplates.org syntax). @ParentIdstring?The @SpanIdof the parent span. Only on spans.@Propertiesobject?User-defined properties. C-style identifiers (e.g., RequestPath) can be accessed implicitly without the@Propertiesprefix.@Resourceobject?OpenTelemetry resource properties. @Scopeobject?OpenTelemetry scope properties. @SpanIdstring?W3C span ID. Log events within a span share this value. @SpanKindstring?OpenTelemetry span kind. Only on spans. @Startnumber?The time the span started. @TimestampnumberThe time the event was recorded. @TraceIdstring?W3C trace ID. All spans/logs in a trace share this. seqcli Usage Tip
When using
seqcli:- Use
--nativeto show results in a round-trippable, agent-friendly syntax. - Use
--jsonfor programmatic use, but note that built-in property names are abbreviated in JSON mode.
- Use
Understand seqcli permissions
devThe operations allowed by an API key are determined by the permissions assigned to it. To find the required permission for a specific
seqclicommand, check the 'Permission demand' column of the equivalent operation in the Seq Server HTTP API documentation.For example, the
apikey createcommand requires theWritepermission.Override configuration with environment variables
devEvery setting in
seqclican be overridden at runtime using environment variables. The format isSEQCLI_<setting path>, where the dotted segments of the setting name are replaced by underscores.Example: To override the
connection.serverUrlsetting, use the environment variableSEQCLI_CONNECTION_SERVERURL.Understand the Seq Type System
devSeq uses a dynamic type system for stored data and expression evaluation. Seq does not perform type coercion. If a function or operator receives invalid arguments, the result is
undefined(similar toNULLin SQL).Supported Types
Type Description Example Literals nullThe atom null.nullbooleanThe atoms trueandfalse.true,falsenumberDecimal numbers (matching .NET decimalprecision).0,12.34,56ms,DateTime('2026-05-29T10:56:01.43278Z'),0xa1b234ffarrayAn ordered array of values. [],[17, null, {a: 'test'}]objectAn unordered set of name/value pairs. {},{a: 'test', 'b c': 17, d: []}anyAn alias for null | boolean | number | array | object.- Note: A type followed by
?(e.g.,number?) indicates the value may beundefined.Understand the Roastery simulation architecture
devThe Roastery project is a simulation of a coffee bean ordering web application. It models a full HTTP stack using an in-memory data structure that flows from a client through middleware and routing to server-side controllers.
The request flow is:
HttpClient$\rightarrow$Middleware$\rightarrow$Router$\rightarrow$Controller.Key components include:
HttpClient: A thin wrapper and factory forHttpRequests that acts as a mock web browser.HttpServer: The base interface for the middleware and routing layer. It defines theInvokeAsyncmethod.Database: A thread-safe in-memory dictionary managing entities likeProductandOrder.Actors: Concurrent entities (e.g.,Customer,WarehouseStaff) that drive the simulation by sending requests via theHttpClient.
// The core interface for the HTTP pipeline abstract class HttpServer { public abstract Task<HttpResponse> InvokeAsync(HttpRequest request); }