Download the latest MSI from datalust.co/download. Also available on Chocolatey and winget.
For Linux or Mac users, use the Docker command:
$ docker run --name seq -d --restart unless-stopped -e ACCEPT_EULA=Y -p 5341:80 datalust/seq:latest
Helm instructions at docs.datalust.co/docs/using-helm.
The Seq UI is served at http://localhost:5341 by default.
Search and query logs. Filter events by selecting signals. Create signals from search expressions to index all matching events, for better search performance.
Create and organize charts based on queries and signals.
View the volume of logs sent to Seq in the last 24 hours. Create and manage API keys and input apps.
View disk usage, check if retention policies are working as expected, add new retention policies.
Enabled authentication. Manage Seq configuration. Install and manage Seq apps. Add users (subscription required).
Create and manage personal API keys, default workspace, and more.
There are two ways to explore log data in Seq:
- Search expressions for filtering and signals
- Queries for analyzing and dashboarding
Run search expressions and queries in the same "search box" by pressing Enter, or clicking
.
Text fragments use "double-quotes", and are a shortcut to searching for logs containing the text between the quotes.
New user created
See note below about no double-quotes
"operation" and not "timed out"
Double-quotes required when operators are used
"New users \"Lucy\" created"
The text fragment "prod" is equivalent to the expression:
@Message like '%prod%' ci or @Exception like '%prod%' ci
Note: If there are no double-quotes around an input, Seq will try to determine if it is a valid search expression before treating it as free text.
You can click on the small text or lambda icon that appears below the filter bar, to inspect your input.
Keywords are not case-sensitive.
ci
and or not
for in
like
true false
null
if then else
select as from stream where group by having order asc desc limit refresh time window
Unlike text fragments, string literals use 'single-quotes' are case-sensitive.
Email = '[email protected]'
Single-quotes required for strings.
Environment = 'PRODUCTION' ci
Environment like 'Prod%'
Single-character wildcard, underscore (_), also supported.
Source = /System.(Web|Api)/
@Exception like '%can''t find host%'
Use a single-quote to escape a single-quote, %% escapes % in like expressions.
= <> like |
Comparators |
Length(text) |
|
ToLower(text) |
|
ToUpper(text) |
|
IndexOf(text, pattern) |
pattern can be a string or regex |
StartsWith(text, pattern) |
|
EndsWith(text, pattern) |
|
Contains(text, pattern) |
|
Substring(text, startIndex, length) |
Pass length as null to capture to end-of-string |
Integers, decimals (floats), and hexadecimal are all represented as 128-bit decimal values.
StatusCode = 200
ElapsedMilliseconds > 1500
StatusCode = ToNumber('401')
= <> > >= < <= |
Comparators |
+ - * / ^ % |
Arithmetic operators |
Round(num, places) |
|
ToNumber(text) |
Like JavaScript, Seq treats null as a value which you can compare using =, <>, in, and other operators. By contrast, the is null operator (inherited from SQL) checks for existence.
OrderId is not null
Has(OrderId) is also valid
OrderId = null
if Quantity = 0 then 'None' else 'Some'
if {expr} then {x} else {y} |
If/then/else |
is null and is not null |
Check for existence |
Coalesce(first, second) |
If first is null, return second, else return first |
Seq uses ticks — total number of 100 nanosecond intervals since 1 Jan, 2001 — as its time representation.
Note: ticks are not the same as milliseconds since Epoch.
There are 10,000 ticks in 1 millisecond.
@Timestamp > DateTime('2020-03-21 14:00:00 +10')
Most valid date and time string formats are supported.
Seq supports duration literals like 1d or 30m as a shorthand way of writing a duration in ticks.
@Timestamp >= Now() - 1d
TimeOfDay(@Timestamp, 10) < 11h
Now() |
Get current time in ticks |
DateTime(text) |
Convert DateTime string to ticks |
ToIsoString(ticks) |
Convert ticks to ISO-8601 string |
TimeOfDay(ticks, offset) |
Convert ticks to time of day |
TimeSpan(timespan) |
Convert timespan string to ticks |
TotalMilliseconds(ticks) |
Convert ticks to ms |
d h m s ms us |
Duration units |
us is microseconds
In Seq, collections include arrays and objects.
User.Email = '[email protected]'
Products[?].Name = 'Coffee'
Post.Tags[*] in ['Seq', '2021']
Order.Shipments[*].Items[*].Tax > 0
@Level in ['Error', 'Warning']
. [?] [*] in |
Dot-accessor, wildcards, and in operator |
Keys(obj) |
Return array of keys in an object |
Values(obj) |
Return array of values in an object |
FromJson(string) |
Convert string to array or object |
ToJson(obj) |
Convert any value to a string |
ElementAt(col, indexer) |
Element at key or index |
Sometimes, we need to check if expressions are doing as we expect.
Debug an expression by wrapping it in a select <expr> from stream limit 1.
select 1 + 1 from stream limit 1
This outputs 2.
Seq uses SQL-like query syntax.
select [<column> [as <label>],]
from stream
[where <predicate>]
[group by [<grouping>|time(<d>),]]
[having <predicate>]
[order by [time|<label>] [asc|desc]]
[limit <n>]
[for refresh]
for refresh is for bypassing the query cache — only use if data is stale.
select count(*) as count
from stream
where StatusCode > 399
group by RequestPath
order by count desc
limit 10
Find the top 10 RequestPaths that have returned a StatusCode of 400, or above.
Seq can generate time series data using the special time() grouping, in conjunction with a duration literal (e.g. 1d, 30m) that determines the time interval to use.
select count(*)
from stream
group by time(15m)
select count(*)
from stream
group by Environment, time(1h)
select count(*)/interval() as RateOfOrders
from stream
where @Properties['Order'] is not null
group by time(5m)
limit 1000
Tip: Chart your query results as a line, bar, or pie chart directly in the events screen, using these buttons:
interval() |
Returns the current time grouping duration. When used in a query with group by time(x), returns x. |
Aggregate functions perform a calculation on a set of values, and return a single value.
select any(@Level = 'Error') from stream...
select count(*) from stream
Counts all events.
select count(IsAdmin) from stream
Counts number of events that contain IsAdmin = true.
select distinct(@Level) from stream
List all distinct @Level values.
select count(distinct(@EventType)) from stream
Count all distinct event types.
select min(Elapsed), max(Elapsed) from stream
Get smallest and largest Elapsed.
select min(Elapsed), max(Elapsed), mean (Elapsed), percentile(Elapsed, 90) from stream group by time(1h)
Plot aggregates over time.
select first(ExceptionType) from stream where Application <> 'Admissions'
Seq uses Serilog's Compact Log Event Format (CLEF) as its native JSON event format. If you export any event from Set, it will look something like below:
{
"@t":"2021-01-26T22:37:02.6297213Z",
"@mt":"HTTP {RequestMethod} {RequestPath} responded {StatusCode}",
"@m":"HTTP GET /example?q=123 responded 501",
"@i":123456, "@l":"Error",
"@x":"System.Threading.Tasks.TaskCancelledException\nAt line...",
"RequestMethod":"GET",
"RequestPath":"/example?q=123",
"StatusCode":501,
"Elapsed":0.75233,
"RequestId":"0AB12C3DE4FGH:00000001",
"Application":"MyExampleApp",
"Site":"Production"
}Here is a table that outlines the relationship between CLEF properties and built-in properties.
You can use built-in properties in search of expressions and queries.
Note: All property names are case-sensitive.
| Description | CLEF | Built-in property | Notes |
|---|---|---|---|
| Timestamp | @t |
@Timestamp |
Timestamp in ticks |
| Message | @m |
@Message |
|
| Event Type | @i |
@EventType |
Maybe a number, or hexadecimal string |
| Event Id | @Id |
e.g. 'event-313db38ac31d...' | |
| Level | @l |
@Level |
|
| Exception | @x |
@Exception |
Usually a stack trace |
| Arrival | @Arrived |
Number representing order of arrival | |
| Properties | @Properties |
All event properties without @ prefix |
|
| Message Template | @mt |
@MessageTemplate |
|
| Data | @Data |
Event as JSON object | |
| Document | @Document |
Event as JSON string |
More details on CLEF at Serilog formatting compact page.

