mirror of https://github.com/dotnet/tye.git
committed by
GitHub
6 changed files with 143 additions and 2 deletions
@ -0,0 +1,50 @@ |
|||
# Logging with Seq |
|||
|
|||
Seq is a popular log-aggregation system that gives you a powerful log search and dashboard engine with views across all of your services. |
|||
|
|||
Tye can push logs to Seq easily without the need for any SDKs or code changes in your services. |
|||
|
|||
## Getting started: running locally with Seq |
|||
|
|||
> :bulb: If you want an existing sample to run, the [sample here](https://github.com/dotnet/tye/tree/master/samples/frontend-backend) will do. This recipe will show examples of UI and data based on that sample. You own application will work fine, but the data and examples will look different. |
|||
|
|||
The first step is to add the `seq` extension to your `tye.yaml`. Add the `extensions` node and its children from the example below. |
|||
|
|||
```yaml |
|||
name: frontend-backend |
|||
|
|||
extensions: |
|||
- name: seq |
|||
logPath: ./.logs |
|||
|
|||
services: |
|||
- name: backend |
|||
project: backend/backend.csproj |
|||
- name: frontend |
|||
project: frontend/frontend.csproj |
|||
``` |
|||
|
|||
The `logPath` property here configures the path where Seq will store its data. |
|||
|
|||
Now launch the application with Tye: |
|||
|
|||
```sh |
|||
tye run |
|||
``` |
|||
|
|||
If you navigate to the Tye dashboard you should see an extra service (`seq`) in the list of services. |
|||
|
|||
|
|||
<img width="1103" alt="image" src="https://user-images.githubusercontent.com/1769935/83251452-f26ffa00-a1ec-11ea-9642-29e4ec579178.png"> |
|||
|
|||
Visit the first URI (`http://localhost:5341`) in your browser to access the Seq dashboard. |
|||
|
|||
Now you're ready to view the data! After it loads, it should look like the screenshot below: |
|||
|
|||
<img width="1515" alt="image" src="https://user-images.githubusercontent.com/1769935/83251005-4cbc8b00-a1ec-11ea-9c76-b7e6db2ef73b.png"> |
|||
|
|||
Now you can see the logs from your application with each field broken out into structured format. If you take advantage of [structured logging](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/logging/?view=aspnetcore-3.1#log-message-template) then you'll see your own data included in structured form here alongside framework logs. |
|||
|
|||
It should like the screenshot below: |
|||
|
|||
<img width="1101" alt="image" src="https://user-images.githubusercontent.com/1769935/83252026-e46ea900-a1ed-11ea-9b96-38695c42dab4.png"> |
|||
@ -0,0 +1,88 @@ |
|||
// Licensed to the .NET Foundation under one or more agreements.
|
|||
// The .NET Foundation licenses this file to you under the MIT license.
|
|||
// See the LICENSE file in the project root for more information.
|
|||
|
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace Microsoft.Tye.Extensions.Seq |
|||
{ |
|||
internal sealed class SeqExtension : Extension |
|||
{ |
|||
public override Task ProcessAsync(ExtensionContext context, ExtensionConfiguration config) |
|||
{ |
|||
if (context.Application.Services.Any(s => s.Name == "seq")) |
|||
{ |
|||
context.Output.WriteDebugLine("seq service already configured. Skipping..."); |
|||
} |
|||
else |
|||
{ |
|||
context.Output.WriteDebugLine("Injecting seq service..."); |
|||
|
|||
var seq = new ContainerServiceBuilder("seq", "datalust/seq") |
|||
{ |
|||
EnvironmentVariables = |
|||
{ |
|||
new EnvironmentVariableBuilder("ACCEPT_EULA") |
|||
{ |
|||
Value = "Y" |
|||
}, |
|||
}, |
|||
Bindings = |
|||
{ |
|||
new BindingBuilder() |
|||
{ |
|||
Port = 5341, |
|||
ContainerPort = 80, |
|||
Protocol = "http", |
|||
}, |
|||
}, |
|||
}; |
|||
context.Application.Services.Add(seq); |
|||
|
|||
if (config.Data.TryGetValue("logPath", out var obj) && |
|||
obj is string logPath && |
|||
!string.IsNullOrEmpty(logPath)) |
|||
{ |
|||
seq.Volumes.Add(new VolumeBuilder(logPath, "seq-data", "/data")); |
|||
} |
|||
|
|||
foreach (var s in context.Application.Services) |
|||
{ |
|||
if (object.ReferenceEquals(s, seq)) |
|||
{ |
|||
continue; |
|||
} |
|||
|
|||
// make seq available as a dependency of everything.
|
|||
if (!s.Dependencies.Contains(seq.Name)) |
|||
{ |
|||
s.Dependencies.Add(seq.Name); |
|||
} |
|||
} |
|||
} |
|||
|
|||
if (context.Operation == ExtensionContext.OperationKind.LocalRun) |
|||
{ |
|||
if (context.Options!.LoggingProvider is null) |
|||
{ |
|||
// For local development we hardcode the port and hostname
|
|||
context.Options.LoggingProvider = "seq=http://localhost:5341"; |
|||
} |
|||
} |
|||
else if (context.Operation == ExtensionContext.OperationKind.Deploy) |
|||
{ |
|||
foreach (var project in context.Application.Services.OfType<DotnetProjectServiceBuilder>()) |
|||
{ |
|||
var sidecar = DiagnosticAgent.GetOrAddSidecar(project); |
|||
|
|||
// Use service discovery to find seq
|
|||
sidecar.Args.Add("--provider:seq=service:seq"); |
|||
sidecar.Dependencies.Add("seq"); |
|||
} |
|||
} |
|||
|
|||
return Task.CompletedTask; |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue