Browse Source

Enable log aggregation in deployed services

pull/450/head
Ryan Nowak 7 years ago
parent
commit
60818e5db3
  1. 1
      samples/.gitignore
  2. 35
      src/Microsoft.Tye.Extensions/DiagnosticAgent.cs
  3. 18
      src/Microsoft.Tye.Extensions/Elastic/ElasticStackExtension.cs
  4. 22
      src/Microsoft.Tye.Extensions/Zipkin/ZipkinExtension.cs
  5. 11
      src/Microsoft.Tye.Hosting.Diagnostics/DiagnosticsProvider.cs
  6. 6
      src/Microsoft.Tye.Hosting/TyeHost.cs
  7. 2
      src/tye-diag-agent/DiagnosticsMonitor.cs
  8. 16
      src/tye-diag-agent/Program.cs

1
samples/.gitignore

@ -0,0 +1 @@
.logs/

35
src/Microsoft.Tye.Extensions/DiagnosticAgent.cs

@ -0,0 +1,35 @@
// 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;
namespace Microsoft.Tye
{
public static class DiagnosticAgent
{
public static SidecarBuilder GetOrAddSidecar(ProjectServiceBuilder project)
{
// Bring your rain boots.
project.RelocateDiagnosticsDomainSockets = true;
var sidecar = project.Sidecars.FirstOrDefault(s => s.Name == "tye-diag-agent");
if (sidecar is object)
{
return sidecar;
}
sidecar = new SidecarBuilder("tye-diag-agent", "rynowak/tye-diag-agent", "0.1")
{
Args =
{
"--kubernetes=true",
$"--service={project.Name}",
$"--assemblyName={project.AssemblyName}",
},
};
project.Sidecars.Add(sidecar);
return sidecar;
}
}
}

18
src/Microsoft.Tye.Extensions/Elastic/ElasticStackExtension.cs

@ -29,14 +29,13 @@ namespace Microsoft.Tye.Extensions.Elastic
{ {
new BindingBuilder() new BindingBuilder()
{ {
Name = "kibbana", Name = "kibana",
Port = 5601, Port = 5601,
ContainerPort = 5601, ContainerPort = 5601,
Protocol = "http", Protocol = "http",
}, },
new BindingBuilder() new BindingBuilder()
{ {
Name = "elastic",
Port = 9200, Port = 9200,
ContainerPort = 9200, ContainerPort = 9200,
Protocol = "http", Protocol = "http",
@ -78,7 +77,20 @@ namespace Microsoft.Tye.Extensions.Elastic
} }
else if (context.Operation == ExtensionContext.OperationKind.Deploy) else if (context.Operation == ExtensionContext.OperationKind.Deploy)
{ {
// TODO: support this :) // For deployments, remove the kibana binding. We don't need to talk to it,
// so don't make the user specify it.
var elastic = context.Application.Services.Single(s => s.Name == "elastic");
var kibana = elastic.Bindings.Single(b => b.Name == "kibana");
elastic.Bindings.Remove(kibana);
foreach (var project in context.Application.Services.OfType<ProjectServiceBuilder>())
{
var sidecar = DiagnosticAgent.GetOrAddSidecar(project);
// Use service discovery to find elastic
sidecar.Args.Add("--provider:elastic=service:elastic");
sidecar.Dependencies.Add("elastic");
}
} }
return Task.CompletedTask; return Task.CompletedTask;

22
src/Microsoft.Tye.Extensions/Zipkin/ZipkinExtension.cs

@ -62,25 +62,11 @@ namespace Microsoft.Tye.Extensions.Zipkin
{ {
foreach (var project in context.Application.Services.OfType<ProjectServiceBuilder>()) foreach (var project in context.Application.Services.OfType<ProjectServiceBuilder>())
{ {
// Bring your rain boots. var sidecar = DiagnosticAgent.GetOrAddSidecar(project);
project.RelocateDiagnosticsDomainSockets = true;
var sidecar = new SidecarBuilder("tye-diag-agent", "rynowak/tye-diag-agent", "0.1") // Use service discovery to find zipkin
{ sidecar.Args.Add("--provider:zipkin=service:zipkin");
Args = sidecar.Dependencies.Add("zipkin");
{
"--kubernetes=true",
"--provider:0=zipkin=service:zipkin",
$"--service={project.Name}",
$"--assemblyName={project.AssemblyName}",
},
Dependencies =
{
// Inject the zipkin service discovery variables
"zipkin",
},
};
project.Sidecars.Add(sidecar);
} }
} }

11
src/Microsoft.Tye.Hosting.Diagnostics/DiagnosticsProvider.cs

@ -19,7 +19,7 @@ namespace Microsoft.Tye
{ "zipkin", new WellKnownProvider("zipkin", ProviderKind.Tracing, "dtrace: Using Zipkin at URL {URL}") }, { "zipkin", new WellKnownProvider("zipkin", ProviderKind.Tracing, "dtrace: Using Zipkin at URL {URL}") },
}; };
public static bool TryParse(string text, ProviderKind kind, [MaybeNullWhen(false)] out DiagnosticsProvider provider) public static bool TryParse(string text, [MaybeNullWhen(false)] out DiagnosticsProvider provider)
{ {
if (string.IsNullOrEmpty(text)) if (string.IsNullOrEmpty(text))
{ {
@ -30,19 +30,18 @@ namespace Microsoft.Tye
var pair = text.Split('='); var pair = text.Split('=');
if (pair.Length < 2) if (pair.Length < 2)
{ {
provider = new DiagnosticsProvider(pair[0].Trim().ToLowerInvariant(), null, kind); provider = new DiagnosticsProvider(pair[0].Trim().ToLowerInvariant(), null);
return true; return true;
} }
provider = new DiagnosticsProvider(pair[0].Trim().ToLowerInvariant(), pair[1].Trim().ToLowerInvariant(), kind); provider = new DiagnosticsProvider(pair[0].Trim().ToLowerInvariant(), pair[1].Trim().ToLowerInvariant());
return true; return true;
} }
public DiagnosticsProvider(string key, string? value, ProviderKind kind) public DiagnosticsProvider(string key, string? value)
{ {
Key = key; Key = key;
Value = value; Value = value;
Kind = kind;
} }
public string Key { get; } public string Key { get; }
@ -51,8 +50,6 @@ namespace Microsoft.Tye
public string? Value { get; } public string? Value { get; }
public ProviderKind Kind { get; }
public enum ProviderKind public enum ProviderKind
{ {
Logging, Logging,

6
src/Microsoft.Tye.Hosting/TyeHost.cs

@ -255,13 +255,13 @@ namespace Microsoft.Tye.Hosting
}; };
if (options.LoggingProvider is string && if (options.LoggingProvider is string &&
DiagnosticsProvider.TryParse(options.LoggingProvider, DiagnosticsProvider.ProviderKind.Logging, out var logging)) DiagnosticsProvider.TryParse(options.LoggingProvider, out var logging))
{ {
diagnosticsCollector.LoggingSink = new LoggingSink(logger, logging); diagnosticsCollector.LoggingSink = new LoggingSink(logger, logging);
} }
if (options.DistributedTraceProvider is string && if (options.DistributedTraceProvider is string &&
DiagnosticsProvider.TryParse(options.DistributedTraceProvider, DiagnosticsProvider.ProviderKind.Tracing, out var tracing)) DiagnosticsProvider.TryParse(options.DistributedTraceProvider, out var tracing))
{ {
diagnosticsCollector.TracingSink = new TracingSink(logger, tracing); diagnosticsCollector.TracingSink = new TracingSink(logger, tracing);
} }
@ -357,7 +357,7 @@ namespace Microsoft.Tye.Hosting
foreach (var text in providerText) foreach (var text in providerText)
{ {
if (DiagnosticsProvider.TryParse(text, DiagnosticsProvider.ProviderKind.Unknown, out var provider)) if (DiagnosticsProvider.TryParse(text, out var provider))
{ {
if (DiagnosticsProvider.WellKnownProviders.TryGetValue(provider.Key, out var wellKnown)) if (DiagnosticsProvider.WellKnownProviders.TryGetValue(provider.Key, out var wellKnown))
{ {

2
src/tye-diag-agent/DiagnosticsMonitor.cs

@ -93,7 +93,7 @@ namespace Microsoft.Tye
continue; continue;
} }
logger.LogInformation(wellKnown.LogFormat, provider.Key); logger.LogInformation(wellKnown.LogFormat, provider.Value);
collector.LoggingSink = new LoggingSink(logger, provider); collector.LoggingSink = new LoggingSink(logger, provider);
break; break;
} }

16
src/tye-diag-agent/Program.cs

@ -30,17 +30,17 @@ namespace Microsoft.Tye
var section = configuration.GetSection("provider"); var section = configuration.GetSection("provider");
foreach (var child in section.GetChildren()) foreach (var child in section.GetChildren())
{ {
if (!DiagnosticsProvider.TryParse(child.Value, DiagnosticsProvider.ProviderKind.Unknown, out var provider))
{
throw new InvalidOperationException("Could not parse diagnostics provider: " + child.Value);
}
// The value used to connect to the service should be accessible with Tye service discovery. // The value used to connect to the service should be accessible with Tye service discovery.
if (provider.Value is string && provider.Value.StartsWith("service:")) DiagnosticsProvider provider;
if (child.Value is string && child.Value.StartsWith("service:"))
{ {
var service = provider.Value.Substring("service:".Length); var service = child.Value.Substring("service:".Length);
var value = configuration.GetServiceUri(service)?.AbsoluteUri ?? configuration.GetConnectionString(service); var value = configuration.GetServiceUri(service)?.AbsoluteUri ?? configuration.GetConnectionString(service);
provider = new DiagnosticsProvider(provider.Key, value, provider.Kind); provider = new DiagnosticsProvider(child.Key, value);
}
else
{
provider = new DiagnosticsProvider(child.Key, child.Value);
} }
options.Providers.Add(provider); options.Providers.Add(provider);

Loading…
Cancel
Save