Commit a4c1716d by huangzhihong

更新 README.md

parent ffde33dd
......@@ -30,6 +30,7 @@
}
```
- [Skywalking 配置](#skywalking)
1. **Console** 配置
- `Program.cs`
......@@ -77,7 +78,7 @@
1. **appsettings.json**
1. 移除所有 `Microsoft.Extension.logging.ILogger` 的配置
1. 移除所有 `Microsoft.Extension.logging` 的相关原生配置
1. 添加 `Serilog` 、`Exceptionless` 的配置
......@@ -241,7 +242,7 @@
Serilog.Log.Logger.Information("Disk quota {Quota} MB exceeded by {Broker}", 12, "RabbitMQ"); //自定义扩展属性 Quota 、Broker
```
1. 检索
1. <b id="exceptionless">检索</b>
> Exceptionless 支持 Key:Value 格式检索
......@@ -256,7 +257,7 @@
![search](./exceptionless-search.png)
## 五、使用 `APM` 扩展日志 —— `SkyWalking`
## <b id="skywalking">五、使用 `APM` 扩展日志 —— `SkyWalking`</b>
1. 客户端
- SkyAPM.Agent.AspNetCore
......@@ -284,3 +285,8 @@
- 通过环境变量 `SKYWALKING__SERVICENAME=sample_app` 配置服务名称,不配置则使用 `skyapm.json``ServiceName`
1. 自定义 `Diagnostic` 上传跟踪信息
1. 追踪与检索
> 通过 `TraceId` 到 `Exceptionless` 检索相关日志,检索方式参考:[Exceptionless检索](#exceptionless)
![search](./skyapm-track.png)
\ No newline at end of file
......@@ -11,6 +11,7 @@
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.1.2" PrivateAssets="All" />
<PackageReference Include="WebApiClient.JIT" Version="1.1.3" />
</ItemGroup>
<ItemGroup>
......
......@@ -29,7 +29,14 @@ namespace SimpleApi.Controllers
//Log.Logger.SetModule("Test2").SetBussinessId("b1").Information("{BusinessId} ......");
//Log.Logger.SetModule("Test2").Information("{BusinessId} ......");
Log.Logger.SetModule("Test3").SetBussinessId("b2").Information("【api1】...{BusinessId} ......");
Serilog.Log.Logger.ForContext(typeof(ValuesController))
.SetModule("库存管理") //扩展属性 Module
.SetBussinessId("ware123sku456") //扩展属性 BusinessId
.SetTags("stock", "incr", "action") //Tag
.AddProperty("CustomProperty1", "CustomValue1") //自定义扩展属性 CustomProperty1
.AddProperty("CustomProperty2", new { Name = "Jack", Age = 18 }) //自定义扩展属性 CustomProperty2
.Information("[api1] Disk quota {Quota} MB exceeded by {Broker}", 12, "RabbitMQ"); //自定义扩展属性 Quota 、Broker
return userApi.GetAsync("dafadfdsfafd").InvokeAsync().GetAwaiter().GetResult();
}
......

using Bailun.ServiceFabric.Trace.Attributes;
using System;
using System.Collections.Generic;
using System.Linq;
......
......@@ -11,6 +11,7 @@
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.1.2" PrivateAssets="All" />
<PackageReference Include="WebApiClient.JIT" Version="1.1.3" />
</ItemGroup>
<ItemGroup>
......

using Bailun.ServiceFabric.Trace.Attributes;
using System.Collections.Generic;
using WebApiClient;
using WebApiClient.Attributes;
......
......@@ -14,43 +14,43 @@ using Bailun.Diagnostics.HttpClient;
using System.Linq;
using Microsoft.Extensions.DependencyInjection.Extensions;
namespace SimpleConsole
{
class Program
namespace SimpleConsole
{
static void Main(string[] args)
class Program
{
CreateHostBuilder(args).Build().Run();
}
static IHostBuilder CreateHostBuilder(string[] args) =>
new HostBuilder()
.UseContentRoot(Directory.GetCurrentDirectory())
.ConfigureHostConfiguration(config =>
static void Main(string[] args)
{
config.AddEnvironmentVariables(prefix: "DOTNET_");
if (args != null)
CreateHostBuilder(args).Build().Run();
}
static IHostBuilder CreateHostBuilder(string[] args) =>
new HostBuilder()
.UseContentRoot(Directory.GetCurrentDirectory())
.ConfigureHostConfiguration(config =>
{
config.AddCommandLine(args);
}
})
.ConfigureAppConfiguration((hostingContext, config) =>
{
var env = hostingContext.HostingEnvironment;
config.AddEnvironmentVariables(prefix: "DOTNET_");
if (args != null)
{
config.AddCommandLine(args);
}
})
.ConfigureAppConfiguration((hostingContext, config) =>
{
var env = hostingContext.HostingEnvironment;
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
})
.ConfigureServices(services =>
{
services.AddHostedService<Worker>();
services.AddHttpApi<IUserApi>(opt =>
})
.ConfigureServices(services =>
{
opt.HttpHost = new Uri("http://localhost:5000/");
});
})
.UseBailunTrace(true, true);
services.AddHostedService<Worker>();
services.AddHttpApi<IUserApi>(opt =>
{
opt.HttpHost = new Uri("http://localhost:5000/");
});
})
.UseBailunTrace(true, true);
}
}
}
......@@ -9,6 +9,7 @@
<PackageReference Include="Microsoft.Extensions.Configuration.CommandLine" Version="2.1.1" />
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="2.1.1" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="2.1.1" />
<PackageReference Include="WebApiClient.JIT" Version="1.1.3" />
</ItemGroup>
<ItemGroup>
......
......@@ -39,7 +39,7 @@ namespace SimpleConsole
await _userApi.GetAsync(index.ToString());
Log.Logger.Information($"【console】...{index}次调用............... ");
Log.Logger.Information($"[console] {index}次调用............... ");
//**************************TODO:业务逻辑**************************
......
using Serilog;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using WebApiClient.Attributes;
using WebApiClient.Contexts;
namespace Bailun.ServiceFabric.Trace.Attributes
{
public class TraceInterceptAttribute : TraceFilterBaseAttribute
{
const string DefaultMessageTemplate =
"HTTP {RequestMethod} {RequestPath} responded {StatusCode}{NewLine}" +
"[REQUEST] {$RequestTime}{NewLine}" +
"{$RequestHeaders}{NewLine}" +
"{$RequestContent}{NewLine}" +
"[RESPONSE] {$ResponseTime}{NewLine}" +
"{$ResponseHeaders}{NewLine}" +
"{$ResponseContent}";
const string RequestMessageTemplate =
"HTTP {RequestMethod} {RequestPath} responded 400 {NewLine}" +
"[REQUEST] {RequestTime}{NewLine}" +
"{RequestHeaders}{NewLine}" +
"{RequestContent}";
const string timeFormat = "yyyy-MM-dd HH:mm:ss.fff";
public TraceInterceptAttribute() { }
public TraceInterceptAttribute(string module)
{
this.Module = module;
}
public string Module { get; set; }
protected override Task LogTraceMessageAsync(ApiActionContext context, TraceMessage traceMessage)
{
var method = context.ApiActionDescriptor.Member;
var actionName = $"{method.DeclaringType.Name}.{method.Name}";
var module = string.IsNullOrWhiteSpace(this.Module) ? actionName : this.Module;
Serilog.Log.Logger.SetModule(module);
var RequestTime = traceMessage.RequestTime.ToString(timeFormat);
var ResponseTime = traceMessage.ResponseTime.ToString(timeFormat);
if (traceMessage.Exception == null)
{
if (traceMessage.HasResponse)
{
if (traceMessage.HasRequest)
{
Serilog.Log.Logger.Information(DefaultMessageTemplate,
context.RequestMessage.Method, context.RequestMessage.RequestUri.PathAndQuery, context.ResponseMessage.StatusCode, System.Environment.NewLine,
traceMessage.RequestTime.ToString(timeFormat), System.Environment.NewLine,
traceMessage.RequestHeaders, System.Environment.NewLine,
traceMessage.RequestContent, System.Environment.NewLine,
traceMessage.ResponseTime.ToString(timeFormat), System.Environment.NewLine,
traceMessage.ResponseHeaders, System.Environment.NewLine,
traceMessage.ResponseContent);
}
}
else if (traceMessage.HasRequest)
{
Serilog.Log.Logger.Information(RequestMessageTemplate,
context.RequestMessage.Method, context.RequestMessage.RequestUri.PathAndQuery, context.ResponseMessage.StatusCode, System.Environment.NewLine,
traceMessage.RequestTime.ToString(timeFormat), System.Environment.NewLine,
traceMessage.RequestHeaders, System.Environment.NewLine,
traceMessage.RequestContent);
}
}
else
{
if (traceMessage.HasResponse)
{
if (traceMessage.HasRequest)
{
Serilog.Log.Logger.Error(traceMessage.Exception, DefaultMessageTemplate,
context.RequestMessage.Method, context.RequestMessage.RequestUri.PathAndQuery, context.ResponseMessage.StatusCode, System.Environment.NewLine,
traceMessage.RequestTime.ToString(timeFormat), System.Environment.NewLine,
traceMessage.RequestHeaders, System.Environment.NewLine,
traceMessage.RequestContent, System.Environment.NewLine,
traceMessage.ResponseTime.ToString(timeFormat), System.Environment.NewLine,
traceMessage.ResponseHeaders, System.Environment.NewLine,
traceMessage.ResponseContent);
}
}
else if (traceMessage.HasRequest)
{
Serilog.Log.Logger.Error(traceMessage.Exception, RequestMessageTemplate,
context.RequestMessage.Method, context.RequestMessage.RequestUri.PathAndQuery, System.Environment.NewLine,
traceMessage.RequestTime.ToString(timeFormat), System.Environment.NewLine,
traceMessage.RequestHeaders, System.Environment.NewLine,
traceMessage.RequestContent);
}
}
return Task.CompletedTask;
}
}
}
......@@ -18,7 +18,6 @@
<PackageReference Include="SkyAPM.Agent.AspNetCore" Version="0.9.0" />
<PackageReference Include="SkyAPM.Agent.GeneralHost" Version="0.9.0" />
<!--<PackageReference Include="SkyAPM.Utilities.DependencyInjection" Version="0.9.0" />-->
<PackageReference Include="WebApiClient.JIT" Version="1.1.3" />
</ItemGroup>
</Project>
......@@ -22,41 +22,55 @@ namespace Microsoft.Extensions.Hosting
/// <returns></returns>
public static IHostBuilder UseBailunTrace(this IHostBuilder builder, bool writeToExceptionless = false, bool writeToConsole = false, Action<LoggerConfiguration> configureLogger = null)
{
Action<HostBuilderContext, LoggerConfiguration> configure = (hostingContext, loggerConfiguration) =>
{
loggerConfiguration
.ReadFrom.Configuration(hostingContext.Configuration)
.Enrich.FromLogContext();
if (writeToExceptionless)
{
var exceptionlessSection = hostingContext.Configuration.GetSection("Exceptionless");
var apiKey = exceptionlessSection.GetValue<string>("ApiKey");
var serverUrl = exceptionlessSection.GetValue<string>("ServerUrl");
loggerConfiguration.WriteTo.Exceptionless(apiKey, serverUrl);
}
if (hostingContext.HostingEnvironment.IsDevelopment())
{
loggerConfiguration.WriteTo.Debug();
}
if (writeToConsole)
{
loggerConfiguration
.WriteTo
.Console(outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {TraceId:l} {Message:lj} {NewLine}{Exception}");
}
};
return builder.UseSerilog(configure)
return builder.UseBailunSerilog(writeToExceptionless, writeToConsole, configureLogger)
.AddSkyAPM()
.ConfigureServices((hostCtx, services) =>
{
services.Replace(ServiceDescriptor.Singleton<ITracingDiagnosticProcessor, HttpClientTracingDiagnosticProcessor>());
});
}
/// <summary>
/// 日志配置
/// </summary>
/// <param name="builder"></param>
/// <param name="writeToExceptionless">是否写到Exceptionless</param>
/// <param name="writeToConsole">是否写到控制台</param>
/// <param name="configureLogger">扩展配置</param>
/// <returns></returns>
public static IHostBuilder UseBailunSerilog(this IHostBuilder builder, bool writeToExceptionless = false, bool writeToConsole = false, Action<LoggerConfiguration> configureLogger = null)
{
Action<HostBuilderContext, LoggerConfiguration> configure = (hostingContext, loggerConfiguration) =>
{
loggerConfiguration
.ReadFrom.Configuration(hostingContext.Configuration)
.Enrich.FromLogContext();
if (writeToExceptionless)
{
var exceptionlessSection = hostingContext.Configuration.GetSection("Exceptionless");
var apiKey = exceptionlessSection.GetValue<string>("ApiKey");
var serverUrl = exceptionlessSection.GetValue<string>("ServerUrl");
loggerConfiguration.WriteTo.Exceptionless(apiKey, serverUrl);
}
if (hostingContext.HostingEnvironment.IsDevelopment())
{
loggerConfiguration.WriteTo.Debug();
}
if (writeToConsole)
{
loggerConfiguration
.WriteTo
.Console(outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {TraceId:l} {Message:lj} {NewLine}{Exception}");
}
configureLogger?.Invoke(loggerConfiguration);
};
return builder.UseSerilog(configure);
}
}
}
......@@ -21,40 +21,55 @@ namespace Microsoft.AspNetCore.Hosting
/// <returns></returns>
public static IWebHostBuilder UseBailunTrace(this IWebHostBuilder builder, bool writeToExceptionless = false, bool writeToConsole = false, Action<LoggerConfiguration> configureLogger = null)
{
Action<WebHostBuilderContext, LoggerConfiguration> configure = (hostingContext, loggerConfiguration) =>
{
loggerConfiguration
.ReadFrom.Configuration(hostingContext.Configuration)
.Enrich.FromLogContext();
if (writeToExceptionless)
{
var exceptionlessSection = hostingContext.Configuration.GetSection("Exceptionless");
var apiKey = exceptionlessSection.GetValue<string>("ApiKey");
var serverUrl = exceptionlessSection.GetValue<string>("ServerUrl");
loggerConfiguration.WriteTo.Exceptionless(apiKey, serverUrl);
}
if (hostingContext.HostingEnvironment.IsDevelopment())
{
loggerConfiguration.WriteTo.Debug();
}
if (writeToConsole)
{
loggerConfiguration
.WriteTo
.Console(outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {TraceId:l} {Message:lj} {NewLine}{Exception}");
}
};
return builder.UseSerilog(configure)
return builder.UseBailunSerilog(writeToExceptionless, writeToConsole, configureLogger)
.ConfigureServices(services =>
{
services.AddSingleton<ITracingDiagnosticProcessor, HostingTracingDiagnosticProcessor>();
services.AddSingleton<ITracingDiagnosticProcessor, HttpClientTracingDiagnosticProcessor>();
});
}
/// <summary>
/// 日志配置
/// </summary>
/// <param name="builder"></param>
/// <param name="writeToExceptionless">是否写到Exceptionless</param>
/// <param name="writeToConsole">是否写到控制台</param>
/// <param name="configureLogger">扩展配置</param>
/// <returns></returns>
public static IWebHostBuilder UseBailunSerilog(this IWebHostBuilder builder, bool writeToExceptionless = false, bool writeToConsole = false, Action<LoggerConfiguration> configureLogger = null)
{
Action<WebHostBuilderContext, LoggerConfiguration> configure = (hostingContext, loggerConfiguration) =>
{
loggerConfiguration
.ReadFrom.Configuration(hostingContext.Configuration)
.Enrich.FromLogContext();
if (writeToExceptionless)
{
var exceptionlessSection = hostingContext.Configuration.GetSection("Exceptionless");
var apiKey = exceptionlessSection.GetValue<string>("ApiKey");
var serverUrl = exceptionlessSection.GetValue<string>("ServerUrl");
loggerConfiguration.WriteTo.Exceptionless(apiKey, serverUrl);
}
if (hostingContext.HostingEnvironment.IsDevelopment())
{
loggerConfiguration.WriteTo.Debug();
}
if (writeToConsole)
{
loggerConfiguration
.WriteTo
.Console(outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {TraceId:l} {Message:lj} {NewLine}{Exception}");
}
configureLogger?.Invoke(loggerConfiguration);
};
return builder.UseSerilog(configure);
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment