Browse Source

Seq Extension (#513)

pull/542/head
Raz Friman 6 years ago
committed by GitHub
parent
commit
c016f38ce0
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      docs/README.md
  2. 0
      docs/recipes/logging_elastic.md
  3. 50
      docs/recipes/logging_seq.md
  4. 88
      src/Microsoft.Tye.Extensions/Seq/SeqExtensions.cs
  5. 2
      src/Microsoft.Tye.Extensions/WellKnownExtensions.cs
  6. 2
      src/Microsoft.Tye.Hosting.Diagnostics/LoggingSink.cs

3
docs/README.md

@ -16,7 +16,8 @@
|-------|------------|
|**[Using Ingress](recipes/ingress.md)** | Using `tye` with an ingress for serving public traffic.
|**[Using Distributed Tracing](recipes/distributed_tracing.md)** | Using zipkin for distributed tracing.
|**[Logging with Elastic Stack](recipes/logging.md)** | Using Elastic Stack for logging.
|**[Logging with Elastic Stack](recipes/logging_elastic.md)** | Using Elastic Stack for logging.
|**[Logging with Seq](recipes/logging_seq.md)** | Using Seq for logging.
|**[Using Dapr with Tye](recipes/dapr.md)** | Using `tye` for local development and deployment with a [Dapr](https://dapr.io) application.

0
docs/recipes/logging.md → docs/recipes/logging_elastic.md

50
docs/recipes/logging_seq.md

@ -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">

88
src/Microsoft.Tye.Extensions/Seq/SeqExtensions.cs

@ -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;
}
}
}

2
src/Microsoft.Tye.Extensions/WellKnownExtensions.cs

@ -6,6 +6,7 @@ using System;
using System.Collections.Generic;
using Microsoft.Tye.Extensions.Dapr;
using Microsoft.Tye.Extensions.Elastic;
using Microsoft.Tye.Extensions.Seq;
using Microsoft.Tye.Extensions.Zipkin;
namespace Microsoft.Tye.Extensions
@ -16,6 +17,7 @@ namespace Microsoft.Tye.Extensions
{
{ "dapr", new DaprExtension() },
{ "elastic", new ElasticStackExtension() },
{ "seq", new SeqExtension() },
{ "zipkin", new ZipkinExtension() },
};
}

2
src/Microsoft.Tye.Hosting.Diagnostics/LoggingSink.cs

@ -170,7 +170,7 @@ namespace Microsoft.Tye.Hosting.Diagnostics
}
// This is the logger factory for application logs. It allows re-routing event pipe collected logs (structured logs)
// to any of the supported sinks, currently (elastic search and app insights)
// to any of the supported sinks, currently (elastic search, console, seq, and app insights)
private void ConfigureLogging(string serviceName, string replicaName, ILoggingBuilder builder)
{
if (string.Equals(_provider.Key, "elastic", StringComparison.OrdinalIgnoreCase) &&

Loading…
Cancel
Save