mirror of
https://github.com/nsnail/Ocelot.git
synced 2025-06-19 07:08:14 +08:00
Improving logging and request id (#189)
* hacking around to work out why logging and request id isnt working * pass request id into logger so it can be structured, removed a bunch of debug logging we dont need because diagnostic trace gets it * changed config dependency * always have tracing available * made it so we dont need to pass config into services.AddOcelot anymore with .net core 2.0 * add test * lots of changes relating to logging and request ids, also updated documentation * fixed failing test i missed
This commit is contained in:
@ -3,11 +3,11 @@ Logging
|
||||
|
||||
Ocelot uses the standard logging interfaces ILoggerFactory / ILogger<T> at the moment.
|
||||
This is encapsulated in IOcelotLogger / IOcelotLoggerFactory with an implementation
|
||||
for the standard asp.net core logging stuff at the moment.
|
||||
for the standard asp.net core logging stuff at the moment. This is because Ocelot add's some extra info to the logs such as request id if it is configured.
|
||||
|
||||
There are a bunch of debugging logs in the ocelot middlewares however I think the
|
||||
system probably needs more logging in the code it calls into. Other than the debugging
|
||||
there is a global error handler that should catch any errors thrown and log them as errors.
|
||||
There is a global error handler that should catch any exceptions thrown and log them as errors.
|
||||
|
||||
Finally if logging is set to trace level Ocelot will log starting, finishing and any middlewares that throw an exception which can be quite useful.
|
||||
|
||||
The reason for not just using bog standard framework logging is that I could not
|
||||
work out how to override the request id that get's logged when setting IncludeScopes
|
||||
|
@ -4,25 +4,57 @@ Request Id / Correlation Id
|
||||
Ocelot supports a client sending a request id in the form of a header. If set Ocelot will
|
||||
use the requestid for logging as soon as it becomes available in the middleware pipeline.
|
||||
Ocelot will also forward the request id with the specified header to the downstream service.
|
||||
I'm not sure if have this spot on yet in terms of the pipeline order becasue there are a few logs
|
||||
that don't get the users request id at the moment and ocelot just logs not set for request id
|
||||
which sucks. You can still get the framework request id in the logs if you set
|
||||
IncludeScopes true in your logging config. This can then be used to match up later logs that do
|
||||
have an OcelotRequestId.
|
||||
|
||||
In order to use the requestid feature in your ReRoute configuration add this setting
|
||||
You can still get the asp.net core request id in the logs if you set
|
||||
IncludeScopes true in your logging config.
|
||||
|
||||
In order to use the reques tid feature you have two options.
|
||||
|
||||
*Global*
|
||||
|
||||
In your configuration.json set the following in the GlobalConfiguration section. This will be used for all requests into Ocelot.
|
||||
|
||||
.. code-block:: json
|
||||
|
||||
"GlobalConfiguration": {
|
||||
"RequestIdKey": "OcRequestId"
|
||||
}
|
||||
|
||||
I reccomend using the GlobalConfiguration unless you really need it to be ReRoute specific.
|
||||
|
||||
*ReRoute*
|
||||
|
||||
If you want to override this for a specific ReRoute add the following to configuration.json for the specific ReRoute.
|
||||
|
||||
.. code-block:: json
|
||||
|
||||
"RequestIdKey": "OcRequestId"
|
||||
|
||||
In this example OcRequestId is the request header that contains the clients request id.
|
||||
Once Ocelot has identified the incoming requests matching ReRoute object it will set the request id based on the ReRoute configuration.
|
||||
|
||||
There is also a setting in the GlobalConfiguration section which will override whatever has been
|
||||
set at ReRoute level for the request id. The setting is as fllows.
|
||||
This can lead to a small gotcha. If you set a GlobalConfiguration it is possible to get one request id until the ReRoute is identified and then another after that because the request id key can change. This is by design and is the best solution I can think of at the moment. In this case the OcelotLogger will show the request id and previous request id in the logs.
|
||||
|
||||
.. code-block:: json
|
||||
Below is an example of the logging when set at Debug level for a normal request..
|
||||
|
||||
"RequestIdKey": "OcRequestId"
|
||||
.. code-block:: bash
|
||||
|
||||
It behaves in exactly the same way as the ReRoute level RequestIdKey settings.
|
||||
dbug: Ocelot.Errors.Middleware.ExceptionHandlerMiddleware[0]
|
||||
requestId: asdf, previousRequestId: no previous request id, message: ocelot pipeline started,
|
||||
dbug: Ocelot.DownstreamRouteFinder.Middleware.DownstreamRouteFinderMiddleware[0]
|
||||
requestId: asdf, previousRequestId: no previous request id, message: upstream url path is {upstreamUrlPath},
|
||||
dbug: Ocelot.DownstreamRouteFinder.Middleware.DownstreamRouteFinderMiddleware[0]
|
||||
requestId: asdf, previousRequestId: no previous request id, message: downstream template is {downstreamRoute.Data.ReRoute.DownstreamPath},
|
||||
dbug: Ocelot.RateLimit.Middleware.ClientRateLimitMiddleware[0]
|
||||
requestId: asdf, previousRequestId: no previous request id, message: EndpointRateLimiting is not enabled for Ocelot.Values.PathTemplate,
|
||||
dbug: Ocelot.Authorisation.Middleware.AuthorisationMiddleware[0]
|
||||
requestId: 1234, previousRequestId: asdf, message: /posts/{postId} route does not require user to be authorised,
|
||||
dbug: Ocelot.DownstreamUrlCreator.Middleware.DownstreamUrlCreatorMiddleware[0]
|
||||
requestId: 1234, previousRequestId: asdf, message: downstream url is {downstreamUrl.Data.Value},
|
||||
dbug: Ocelot.Request.Middleware.HttpRequestBuilderMiddleware[0]
|
||||
requestId: 1234, previousRequestId: asdf, message: setting upstream request,
|
||||
dbug: Ocelot.Requester.Middleware.HttpRequesterMiddleware[0]
|
||||
requestId: 1234, previousRequestId: asdf, message: setting http response message,
|
||||
dbug: Ocelot.Responder.Middleware.ResponderMiddleware[0]
|
||||
requestId: 1234, previousRequestId: asdf, message: no pipeline errors, setting and returning completed response,
|
||||
dbug: Ocelot.Errors.Middleware.ExceptionHandlerMiddleware[0]
|
||||
requestId: 1234, previousRequestId: asdf, message: ocelot pipeline finished,
|
||||
|
@ -1,9 +1,11 @@
|
||||
Getting Started
|
||||
===============
|
||||
|
||||
Ocelot is designed to work with ASP.NET core only and is currently
|
||||
Ocelot is designed to work with .NET Core only and is currently
|
||||
built to netcoreapp2.0 `this <https://docs.microsoft.com/en-us/dotnet/articles/standard/library>`_ documentation may prove helpful when working out if Ocelot would be suitable for you.
|
||||
|
||||
.NET Core 2.0
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
**Install NuGet package**
|
||||
|
||||
@ -30,6 +32,86 @@ The following is a very basic configuration.json. It won't do anything but shoul
|
||||
Then in your Program.cs you will want to have the following. This can be changed if you
|
||||
don't wan't to use the default url e.g. UseUrls(someUrls) and should work as long as you keep the WebHostBuilder registration.
|
||||
|
||||
.. code-block:: csharp
|
||||
|
||||
public class Program
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
IWebHostBuilder builder = new WebHostBuilder();
|
||||
builder.ConfigureServices(s => {
|
||||
s.AddSingleton(builder);
|
||||
});
|
||||
builder.UseKestrel()
|
||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
||||
.ConfigureAppConfiguration((hostingContext, config) =>
|
||||
{
|
||||
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
|
||||
var env = hostingContext.HostingEnvironment;
|
||||
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
||||
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
|
||||
config.AddJsonFile("configuration.json");
|
||||
config.AddEnvironmentVariables();
|
||||
})
|
||||
.ConfigureLogging((hostingContext, logging) =>
|
||||
{
|
||||
logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
|
||||
logging.AddConsole();
|
||||
})
|
||||
.UseIISIntegration()
|
||||
.UseStartup<ManualTestStartup>();
|
||||
var host = builder.Build();
|
||||
host.Run();
|
||||
}
|
||||
}
|
||||
|
||||
Sadly we need to inject the IWebHostBuilder interface to get the applications scheme, url and port later. I cannot find a better way of doing this at the moment without setting this in a static or some kind of config.
|
||||
|
||||
**Startup**
|
||||
|
||||
An example startup using a json file for configuration can be seen below. This is the most basic startup and Ocelot has quite a few more options. Detailed in the rest of these docs! If you get a stuck a good place to look is at the ManualTests project in the source code.
|
||||
|
||||
.. code-block:: csharp
|
||||
|
||||
public class Startup
|
||||
{
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services.AddOcelot();
|
||||
}
|
||||
|
||||
public void Configure(IApplicationBuilder app)
|
||||
{
|
||||
app.UseOcelot().Wait();
|
||||
}
|
||||
}
|
||||
|
||||
.NET Core 1.0
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
**Install NuGet package**
|
||||
|
||||
Install Ocelot and it's dependecies using nuget. You will need to create a netcoreapp1.0+ projct and bring the package into it. Then follow the Startup below and :doc:`../features/configuration` sections
|
||||
to get up and running. Please note you will need to choose one of the Ocelot packages from the NuGet feed.
|
||||
|
||||
All versions can be found `here <https://www.nuget.org/packages/Ocelot/>`_.
|
||||
|
||||
**Configuration**
|
||||
|
||||
The following is a very basic configuration.json. It won't do anything but should get Ocelot starting.
|
||||
|
||||
.. code-block:: json
|
||||
|
||||
{
|
||||
"ReRoutes": [],
|
||||
"GlobalConfiguration": {}
|
||||
}
|
||||
|
||||
**Program**
|
||||
|
||||
Then in your Program.cs you will want to have the following. This can be changed if you
|
||||
don't wan't to use the default url e.g. UseUrls(someUrls) and should work as long as you keep the WebHostBuilder registration.
|
||||
|
||||
.. code-block:: csharp
|
||||
|
||||
public class Program
|
||||
@ -57,7 +139,6 @@ Sadly we need to inject the IWebHostBuilder interface to get the applications sc
|
||||
**Startup**
|
||||
|
||||
An example startup using a json file for configuration can be seen below.
|
||||
Currently this is the only way to get configuration into Ocelot.
|
||||
|
||||
.. code-block:: csharp
|
||||
|
||||
@ -79,22 +160,13 @@ Currently this is the only way to get configuration into Ocelot.
|
||||
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services.AddOcelot(Configuration)
|
||||
.AddCacheManager(x => {
|
||||
x.WithMicrosoftLogging(log =>
|
||||
{
|
||||
log.AddConsole(LogLevel.Debug);
|
||||
})
|
||||
.WithDictionaryHandle();
|
||||
});;
|
||||
}
|
||||
services.AddOcelot(Configuration);
|
||||
}
|
||||
|
||||
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
|
||||
public void Configure(IApplicationBuilder app)
|
||||
{
|
||||
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
|
||||
|
||||
app.UseOcelot().Wait();
|
||||
}
|
||||
}
|
||||
|
||||
This is pretty much all you need to get going.......more to come!
|
||||
This is pretty much all you need to get going.
|
Reference in New Issue
Block a user