VOOZH about

URL: https://www.nuget.org/packages/Serilog.Sinks.Grafana.Loki/

⇱ NuGet Gallery | Serilog.Sinks.Grafana.Loki 9.0.0


ο»Ώ

πŸ‘ Image
Serilog.Sinks.Grafana.Loki 9.0.0

dotnet add package Serilog.Sinks.Grafana.Loki --version 9.0.0
 
 
NuGet\Install-Package Serilog.Sinks.Grafana.Loki -Version 9.0.0
 
 
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Serilog.Sinks.Grafana.Loki" Version="9.0.0" />
 
 
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Serilog.Sinks.Grafana.Loki" Version="9.0.0" />
 
Directory.Packages.props
<PackageReference Include="Serilog.Sinks.Grafana.Loki" />
 
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Serilog.Sinks.Grafana.Loki --version 9.0.0
 
 
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
#r "nuget: Serilog.Sinks.Grafana.Loki, 9.0.0"
 
 
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Serilog.Sinks.Grafana.Loki@9.0.0
 
 
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Serilog.Sinks.Grafana.Loki&version=9.0.0
 
Install as a Cake Addin
#tool nuget:?package=Serilog.Sinks.Grafana.Loki&version=9.0.0
 
Install as a Cake Tool
The NuGet Team does not provide support for this client. Please contact its maintainers for support.

Serilog.Sinks.Grafana.Loki

πŸ‘ Made in Ukraine
πŸ‘ Build status
πŸ‘ NuGet version
πŸ‘ Latest release
πŸ‘ Documentation

Terms of use

By using this project or its source code, for any purpose and in any shape or form, you grant your **implicit agreement ** to all the following statements:

  • You condemn Russia and its military aggression against Ukraine
  • You recognize that Russia is an occupant that unlawfully invaded a sovereign state
  • You support Ukraine's territorial integrity, including its claims over temporarily occupied territories of Crimea and Donbas
  • You reject false narratives perpetuated by Russian state propaganda

Glory to Ukraine! πŸ‡ΊπŸ‡¦

Table of contents

<a id="what-is-this"></a>What is this sink and Loki?

The Serilog Grafana Loki sink project is a sink (basically a writer) for the Serilog logging framework. Structured log events are written to sinks and each sink is responsible for writing it to its own backend, database, store etc. This sink delivers the data to Grafana Loki, a horizontally-scalable, highly-available, multi-tenant log aggregation system. It allows you to use Grafana for visualizing your logs.

You can find more information about what Loki is over on Grafana's website here.

<a id="whats-new-in-v9"></a>What's new in V9

V9 is a ground-up rewrite of the sink in F#, keeping a public API that remains idiomatic to call from C#. The rewrite fixes a class of long-standing structural bugs and modernizes the delivery pipeline:

  • Built on Serilog 4.x native batching. The custom queue/timer/backoff stack is gone. Delivery now uses Serilog's IBatchedLogEventSink, giving a bounded queue by default (50 000 events), async emission, and retry with exponential backoff β€” no more dropped batches on failure and no dispose-time deadlocks.
  • Immutable log-event pipeline. Labels are derived from a read-only view of the event. Properties promoted to labels now also remain in the log body, and the message template is never corrupted on retry.
  • Streaming serialization. Payloads are written in a single forward pass with Utf8JsonWriter over pooled buffers β€” no intermediate object graph and no intermediate strings.
  • Bring-your-own HttpClient / HttpMessageHandler. The old ILokiHttpClient/LokiGzipHttpClient hierarchy is replaced by direct injection; gzip, retries, mTLS and bearer auth are now standard DelegatingHandler concerns.
  • New features: pluggable exception formatter (ILokiExceptionFormatter), TraceId/SpanId routing to the body or Loki structured metadata, startup URI validation, and the log level exposed as a label using Grafana's vocabulary.

See Migrating from V8 for the full list of breaking changes.

<a id="requirements"></a>Requirements

  • .NET: net8.0, net9.0, or net10.0 (earlier target frameworks are EOL and no longer supported).
  • Serilog: 4.3.1 or later.
  • Transitive dependency: FSharp.Core is pulled in automatically. No other sink packages are required.

<a id="features"></a>Features

  • Batches and ships structured log events to Loki over its HTTP push API
  • Serilog 4.x native batching: bounded in-memory queue, retry with exponential backoff, fully async emission
  • Streaming System.Text.Json serialization with pooled buffers (no intermediate object graph or strings)
  • Global and property-derived labels with deterministic stream grouping and key sanitisation
  • Log level exposed as a label using Grafana's level vocabulary (optional)
  • Basic authentication and multi-tenancy (X-Scope-OrgID) support
  • Bring-your-own HttpClient / HttpMessageHandler β€” gzip, retries, mTLS and bearer auth via DelegatingHandler
  • TraceId / SpanId from the ambient Activity (OpenTelemetry) β€” written to the log body or as structured metadata
  • Loki structured metadata: per-line, non-indexed key/value pairs, queryable without a parser and without label cardinality cost (Loki 3.0+)
  • Pluggable exception formatter and text formatter
  • First-class Serilog.Settings.Configuration (appsettings.json) support
  • No dependency on any other Serilog sink

<a id="quickstart"></a>Quickstart

The Serilog.Sinks.Grafana.Loki NuGet package can be found here. Install it via one of the following commands:

NuGet command:

Install-Package Serilog.Sinks.Grafana.Loki

.NET CLI:

dotnet add package Serilog.Sinks.Grafana.Loki

In the following example, the sink will send log events to Loki available on http://localhost:3100:

using Serilog;
using Serilog.Sinks.Grafana.Loki;

Log.Logger = new LoggerConfiguration()
 .WriteTo.GrafanaLoki(
 "http://localhost:3100",
 [new LokiLabel { Key = "app", Value = "web_app" }])
 .CreateLogger();

Log.Information("The god of the day is {@God}", odin);

The sink posts to <uri>/loki/api/v1/push. The push path is appended automatically β€” pass only the base address (a path prefix such as http://gateway/loki is supported and preserved).

Used together with Serilog.Settings.Configuration, the same sink can be configured from appsettings.json:

{
 "Serilog": {
 "Using": [
 "Serilog.Sinks.Grafana.Loki"
 ],
 "MinimumLevel": {
 "Default": "Debug"
 },
 "WriteTo": [
 {
 "Name": "GrafanaLoki",
 "Args": {
 "uri": "http://localhost:3100",
 "labels": [
 {
 "key": "app",
 "value": "web_app"
 }
 ],
 "propertiesAsLabels": [
 "app"
 ]
 }
 }
 ]
 }
}

<a id="configuration-reference"></a>Configuration reference

All options are passed as named arguments to WriteTo.GrafanaLoki(...). Only uri is required.

Parameter Type Default Description
uri string β€” (required) Loki base URI, e.g. http://localhost:3100. Validated at startup; must be an absolute http/https URI.
labels LokiLabel[] [] Static labels attached to every stream.
propertiesAsLabels string[] [] Log-event property names to promote to stream labels.
propertiesAsStructuredMetadata string[] [] Property names to attach as per-line structured metadata (non-indexed; Loki 3.0+).
handleLogLevelAsLabel bool true Add a level label using Grafana's level vocabulary.
credentials LokiCredentials null Basic-auth credentials. From appsettings.json, an object with login/password.
tenant string null Value for the X-Scope-OrgID multi-tenancy header; validated at startup.
traceIdMode LokiFieldDestination None Where to write the event's TraceId: None, Body, or StructuredMetadata.
spanIdMode LokiFieldDestination None Where to write the event's SpanId: None, Body, or StructuredMetadata.
batchSizeLimit int 1000 Maximum events per HTTP POST.
queueLimit int 50000 Maximum events buffered in memory before new events are dropped.
period TimeSpan? 1 s Flush interval. From appsettings.json, written as an "hh:mm:ss" string.
eagerlyEmitFirstEvent bool true Flush immediately on the first event (surfaces misconfiguration early).
retryTimeLimit TimeSpan? 10 min Stop retrying a failed batch after this duration. From appsettings.json, an "hh:mm:ss" string.
textFormatter ITextFormatter LokiJsonTextFormatter Per-event body formatter.
exceptionFormatter ILokiExceptionFormatter LokiExceptionFormatter Exception serializer.
httpClient HttpClient null Pre-built client (e.g. from IHttpClientFactory). The sink never disposes an injected client.
httpMessageHandler HttpMessageHandler null Handler for the sink's own client (gzip, retries, …). Ignored when httpClient is set.
restrictedToMinimumLevel LogEventLevel Verbose Minimum level handled by this sink.

Note on period / retryTimeLimit: in C# these are TimeSpan? (e.g. period: TimeSpan.FromSeconds(5)); leave them unset to use the defaults. In appsettings.json they are written as "hh:mm:ss" strings (e.g. "00:00:05"), which Serilog.Settings.Configuration converts to TimeSpan.

A more complete C# example:

Log.Logger = new LoggerConfiguration()
 .WriteTo.GrafanaLoki(
 "http://localhost:3100",
 labels: [new LokiLabel { Key = "app", Value = "my-service" }],
 propertiesAsLabels: ["RequestPath"],
 credentials: new LokiCredentials { Login = "user", Password = "pass" },
 tenant: "my-tenant",
 traceIdMode: LokiFieldDestination.StructuredMetadata,
 queueLimit: 100_000,
 period: TimeSpan.FromSeconds(2))
 .CreateLogger();

Configuration details for appsettings.json are also documented in the wiki.

<a id="labels"></a>Labels

Each log event is mapped to a Loki stream identified by its label set. Events that resolve to the same label set are grouped into one stream and ordered by timestamp.

Labels come from three sources, in descending priority:

  1. Global labels β€” from the labels option, attached to every stream.
  2. The level label β€” added when handleLogLevelAsLabel is true (the default).
  3. Property-derived labels β€” from propertiesAsLabels.

When keys collide, a higher-priority source wins; a property is silently skipped if its key matches a global label or the reserved level key. Unlike V8, properties promoted to labels are kept in the log body as well β€” promotion no longer removes them from the event.

Other rules:

  • Key sanitisation: label keys must begin with a letter or underscore. Keys that start with a digit (for example positional template tokens like {0}) are prefixed with param, becoming param0.
  • Level vocabulary: Serilog levels map to Grafana's level names β€” Verbose β†’ trace, Debug β†’ debug, Information β†’ info, Warning β†’ warning, Error β†’ error, Fatal β†’ fatal (previously critical).

<a id="authentication-and-multi-tenancy"></a>Authentication and multi-tenancy

Basic authentication is configured with a credentials object:

.WriteTo.GrafanaLoki(
 "http://localhost:3100",
 credentials: new LokiCredentials { Login = "user", Password = "pass" })

Basic auth is applied only to a client the sink creates. If you inject your own httpClient, configure its Authorization header yourself β€” the sink never mutates an injected client.

Multi-tenancy is configured with tenant, which sets the X-Scope-OrgID header:

.WriteTo.GrafanaLoki("http://localhost:3100", tenant: "tenant-1")

The tenant ID is validated at configuration time against Loki's tenant ID rules β€” alphanumerics plus !-_.*'(), at most 150 bytes, and not . or .. β€” an invalid value throws ArgumentException instead of producing batches Loki would reject.

Bearer tokens / OAuth2 are not a first-class option β€” add them through the injected client, either by setting a default Authorization header on an HttpClient or via a DelegatingHandler (see below).

<a id="custom-http-client"></a>Custom HttpClient

V9 accepts a standard HttpClient or HttpMessageHandler directly. Inject your own to add gzip compression, retries, mTLS, bearer auth, or any other cross-cutting behaviour:

// GzipHandler.cs
using System.IO.Compression;
using System.Net.Http;
using System.Net.Http.Headers;

public class GzipHandler : DelegatingHandler
{
 public GzipHandler() : base(new HttpClientHandler()) { }

 protected override async Task<HttpResponseMessage> SendAsync(
 HttpRequestMessage request, CancellationToken ct)
 {
 if (request.Content is not null)
 {
 var bytes = await request.Content.ReadAsByteArrayAsync(ct);
 using var ms = new MemoryStream();
 using (var gz = new GZipStream(ms, CompressionLevel.Fastest, leaveOpen: true))
 await gz.WriteAsync(bytes, ct);
 request.Content = new ByteArrayContent(ms.ToArray());
 request.Content.Headers.ContentType =
 new MediaTypeHeaderValue("application/json") { CharSet = "utf-8" };
 request.Content.Headers.ContentEncoding.Add("gzip");
 }
 return await base.SendAsync(request, ct);
 }
}
// Inject via httpMessageHandler β€” the sink creates and owns the HttpClient
// (and still applies basic auth / tenant headers).
Log.Logger = new LoggerConfiguration()
 .WriteTo.GrafanaLoki(
 "http://localhost:3100",
 httpMessageHandler: new GzipHandler())
 .CreateLogger();

// Or inject a pre-built HttpClient (e.g. from IHttpClientFactory β€” the sink never disposes it).
var httpClient = httpClientFactory.CreateClient("loki");
Log.Logger = new LoggerConfiguration()
 .WriteTo.GrafanaLoki(
 "http://localhost:3100",
 httpClient: httpClient)
 .CreateLogger();

<a id="trace-and-span-enrichment"></a>Trace and span context

traceIdMode and spanIdMode control where the event's TraceId / SpanId (populated by Serilog 4.x from the ambient Activity) are written. Each takes a LokiFieldDestination:

Value Effect
None (default) Not emitted.
Body Written as a TraceId / SpanId field in the JSON log body.
StructuredMetadata Attached as Loki structured metadata β€” recommended for trace IDs.
.WriteTo.GrafanaLoki(
 "http://localhost:3100",
 traceIdMode: LokiFieldDestination.StructuredMetadata,
 spanIdMode: LokiFieldDestination.StructuredMetadata)

From appsettings.json the mode binds from its name: "traceIdMode": "StructuredMetadata".

Trace context is typically populated for you by Serilog.AspNetCore / Serilog.Extensions.Logging; outside those, an active Activity must be present for the IDs to be emitted.

<a id="structured-metadata"></a>Structured metadata

Structured metadata attaches per-line key/value pairs to a log entry without indexing them as labels. Unlike propertiesAsLabels it does not create new streams (no cardinality cost), and unlike a body field it is queryable without a parser stage:

{app="web_app"} | RequestId="abc-123" # structured metadata β€” no parser needed
{app="web_app"} | json | RequestId="abc-123" # the equivalent for a body field

That makes it the right home for high-cardinality identifiers such as request, user, or trace IDs. Two sources feed it:

  • propertiesAsStructuredMetadata β€” property names to attach as metadata (the property is also kept in the body).
  • traceIdMode / spanIdMode set to StructuredMetadata β€” routes TraceId / SpanId there instead of the body.
.WriteTo.GrafanaLoki(
 "http://localhost:3100",
 propertiesAsStructuredMetadata: ["RequestId", "UserId"],
 traceIdMode: LokiFieldDestination.StructuredMetadata)

It is emitted as the optional third element of each push entry:

"values": [
 [ "1700000000000000000", "{\"Message\":\"...\"}", { "RequestId": "abc-123", "TraceId": "..." } ]
]

Requires Loki 3.0+ (or 2.9 with allow_structured_metadata enabled on a TSDB v13 schema). Against an older Loki, or one with structured metadata disabled, such a push is rejected β€” leave these options unset (the default) to stay compatible.

For the full picture β€” the three-tier model (labels vs structured metadata vs body), querying, and Loki configuration β€” see Structured metadata in the wiki.

<a id="json-formatting"></a>JSON formatting and custom formatters

By default the sink uses LokiJsonTextFormatter, which renders each log entry's body as a JSON object. This makes logs easy to filter in Loki β€” see Grafana's write-up on querying JSON logs.

The resulting push payload looks like:

{
 "streams": [
 {
 "stream": { "app": "web_app", "level": "info" },
 "values": [
 [ "1700000000000000000", "{\"Message\":\"...\",\"MessageTemplate\":\"...\"}" ]
 ]
 }
 ]
}

Each body object contains Message, MessageTemplate, an optional Exception, the TraceId / SpanId fields (when their mode is Body), and every event property. Property names that collide with these reserved keys (Message, MessageTemplate, Exception, TraceId, SpanId) are prefixed with _.

Custom text formatter. Implement Serilog.Formatting.ITextFormatter, or subclass LokiJsonTextFormatter and override Format or SanitizePropertyName, then pass it via textFormatter:

{
 "Serilog": {
 "WriteTo": [
 {
 "Name": "GrafanaLoki",
 "Args": {
 "uri": "http://localhost:3100",
 "textFormatter": "My.Awesome.Namespace.MyTextFormatter, MyCoolAssembly"
 }
 }
 ]
 }
}

Custom exception formatter. Exception serialization is delegated to ILokiExceptionFormatter. The default (LokiExceptionFormatter) recursively writes Type, Message, Source, StackTrace and inner exceptions. Replace it to scrub PII, change the shape, or suppress stack traces:

using System.Text.Json;
using Serilog.Sinks.Grafana.Loki;

public class CompactExceptionFormatter : ILokiExceptionFormatter
{
 public void Format(Utf8JsonWriter writer, Exception exception)
 {
 writer.WriteStartObject();
 writer.WriteString("type", exception.GetType().Name);
 writer.WriteString("message", exception.Message);
 writer.WriteEndObject();
 }
}
.WriteTo.GrafanaLoki(
 "http://localhost:3100",
 exceptionFormatter: new CompactExceptionFormatter())

<a id="batching-and-delivery"></a>Batching and delivery

Delivery is handled by Serilog 4.x's native batching infrastructure:

  • Events are buffered and flushed every period (default 1 s) or once batchSizeLimit (default 1000) is reached.
  • The in-memory queue is bounded at queueLimit (default 50 000). When the queue is full, new events are dropped rather than growing memory without limit.
  • On a failed POST, the batch is retried with exponential backoff up to retryTimeLimit (default 10 min), after which it is dropped so the pipeline can make progress.
  • Emission is fully asynchronous, so disposing the logger (Log.CloseAndFlush()) flushes cleanly without deadlocks.

Delivery problems are reported through Serilog's SelfLog. Enable it during development to see HTTP errors and dropped batches:

Serilog.Debugging.SelfLog.Enable(Console.Error);

<a id="migrating-from-v8"></a>Migrating from V8

V9 is a major release with breaking changes. The highlights:

Area V8 V9
Target frameworks netstandard2.0, net5.0–net8.0 net8.0, net9.0, net10.0
Serilog 2.x / 3.x 4.3.1+ (native batching)
HTTP client ILokiHttpClient / LokiGzipHttpClient subclasses Inject httpClient / httpMessageHandler; gzip via DelegatingHandler
Level label always injected, collisions renamed handleLogLevelAsLabel (default true); Fatal β†’ fatal (was critical)
Property β†’ label removed the property from the body property is kept in the body
Reserved-property renaming IReservedPropertyRenamingStrategy removed β€” pipeline is immutable; reserved body keys are prefixed with _
leavePropertiesIntact flag removed β€” no longer needed
useInternalTimestamp flag removed
Queue unbounded by default bounded at queueLimit (default 50 000)
Exception formatting hardcoded pluggable ILokiExceptionFormatter
Trace context not supported traceIdMode / spanIdMode (body or structured metadata)
URI validation on first request at logger configuration time

FSharp.Core becomes a transitive dependency of all consumers.

The full, maintained list of breaking changes lives in the wiki.

<a id="samples"></a>Samples

Runnable examples live in the folder:

  • Serilog.Sinks.Grafana.Loki.Sample β€” a minimal console app.
  • Serilog.Sinks.Grafana.Loki.SampleWebApp β€” an ASP.NET Core app configured from appsettings.json.

<a id="inspiration-and-credits"></a>Inspiration and Credits

  • Serilog.Sinks.Loki β€” the original Serilog Loki sink, which this project was born from and inspired by.
  • Serilog.Sinks.Loki.YetAnother β€” an allocation-conscious Loki sink whose performance findings inspired parts of the V9 optimization work; it also serves as the external yardstick in our .
Product Versions Compatible and additional computed target framework versions.
.NET net8.0 net8.0 is compatible.  net8.0-android net8.0-android was computed.  net8.0-browser net8.0-browser was computed.  net8.0-ios net8.0-ios was computed.  net8.0-maccatalyst net8.0-maccatalyst was computed.  net8.0-macos net8.0-macos was computed.  net8.0-tvos net8.0-tvos was computed.  net8.0-windows net8.0-windows was computed.  net9.0 net9.0 is compatible.  net9.0-android net9.0-android was computed.  net9.0-browser net9.0-browser was computed.  net9.0-ios net9.0-ios was computed.  net9.0-maccatalyst net9.0-maccatalyst was computed.  net9.0-macos net9.0-macos was computed.  net9.0-tvos net9.0-tvos was computed.  net9.0-windows net9.0-windows was computed.  net10.0 net10.0 is compatible.  net10.0-android net10.0-android was computed.  net10.0-browser net10.0-browser was computed.  net10.0-ios net10.0-ios was computed.  net10.0-maccatalyst net10.0-maccatalyst was computed.  net10.0-macos net10.0-macos was computed.  net10.0-tvos net10.0-tvos was computed.  net10.0-windows net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (86)

Showing the top 5 NuGet packages that depend on Serilog.Sinks.Grafana.Loki:

Package Downloads
Convey.Logging

Convey.Logging

Genocs.Logging

Logging abstractions and extensions for Genocs applications.

Bones.Monitoring

Package Description

MosFlightWidgetHelper

Package Description

Only.CoffeeFace.Web

Only.CoffeeFace web api stuff

GitHub repositories (14)

Showing the top 14 popular GitHub repositories that depend on Serilog.Sinks.Grafana.Loki:

Repository Stars
slskd/slskd
A modern client-server application for the Soulseek file sharing network.
GZTimeWalker/GZCTF
The GZ::CTF project, an open source CTF platform.
MUnique/OpenMU
This project aims to create an easy to use, extendable and customizable server for a MMORPG called "MU Online".
mehdihadeli/food-delivery-microservices
πŸ” A practical and cloud-native food delivery microservices, built with .Net Aspire, .Net 9, MassTransit, Domain-Driven Design, CQRS, Vertical Slice Architecture, Event-Driven Architecture, and the latest technologies.
snatch-dev/Convey
A simple recipe for .NET Core microservices.
mizrael/SuperSafeBank
Sample Event Sourcing implementation with .NET Core
TanvirArjel/CleanArchitecture
This repository contains the implementation of domain-driven design and clear architecture in ASP.NET Core.
compujuckel/AssettoServer
Custom Assetto Corsa server with focus on freeroam
philosowaffle/peloton-to-garmin
Convert workout data from Peloton into JSON/TCX/FIT files and automatically upload to Garmin Connect
mehdihadeli/vertical-slice-api-template
🍰 An asp.net core template based on .Net 9, Vertical Slice Architecture, CQRS, Minimal APIs, OpenTelemetry, API Versioning and OpenAPI.
Letterbook/Letterbook
Sustainable federated social media built for open correspondence
asynkron/realtimemap-dotnet
A showcase for Proto.Actor - an ultra-fast distributed actors solution for Go, C#, and Java/Kotlin.
marinasundstrom/YourBrand
Prototype enterprise system for e-commerce and consulting services
Dubzer/TgTranslator
Telegram bot that translates messages in groups
Version Downloads Last Updated
9.0.0 16,735 6/6/2026
8.3.2 1,203,611 12/30/2025
8.3.1 2,231,717 6/4/2025
8.3.0 7,589,592 1/30/2024
8.2.0 1,165,121 10/30/2023
8.2.0-beta.3 236 10/28/2023
8.2.0-beta.2 10,937 10/5/2023
8.2.0-beta.1 17,318 7/17/2023
8.2.0-beta.0 321 7/10/2023
8.1.0 3,572,129 11/26/2022
8.0.1 365,424 10/13/2022
8.0.0 622,071 7/19/2022
8.0.0-beta.0 8,993 4/1/2022
7.1.1 1,226,938 3/23/2022
7.1.0 1,149,199 9/21/2021
7.0.2 54,510 8/30/2021
7.0.1 18,035 8/17/2021
7.0.0 14,508 8/15/2021
6.0.1 142,438 6/7/2021
Loading failed

For release notes, please see the change log on GitHub.