Log File actuator
I'd like to discuss adding the logfile actuator. If this is something the team would be open to, I'm happy to work the issue.
My use case: I have multiple services in production across a few different environments (Cloud Foundry, K8s, Azure AppServices) that all use either Steeltoe or Spring Boot. The .NET services use Serilog.
I monitor them with Spring Boot Admin. I don't want to incur the cost of running a centralized logging system like Loki as it's a bit overkill for my needs. As it exists right now, I can configure the logging levels of all of my services through SBA, but only view the logfile of the Spring Boot services.
My desired behavior: I'd like to specify a
management:endpoints:logfile:filepathproperty and enable a/actuator/logfilemanagement endpoint which would serve the contents of that file astext/plain.
Originally posted by @tscrypter in #668
My first pass idea was to provide an actuator that with the following config settings (prefixed with Management:Endpoints:Logfile.
| Key | Description | Default |
|---|---|---|
| Enabled | Whether the endpoint is enabled | true |
| ID | The unique ID of the endpoint | logfile |
| Path | The relative path at which the endpoint is exposed | logfile |
| RequiredPermissions | Permissions required to access the endpoint, when running on Cloud Foundry | Restricted |
| AllowedVerbs | An array of HTTP verbs the endpoint is exposed at. | GET |
| FilePath | The relative path to the log file that will be exposed | Logs/log.txt |
The FilePath default I just aligned with the example config from serilog/serilog-settings-configuration.
If no file is found, I was planning on just having the endpoint serve a 404. Does this sound like an OK pass? If so, I can probably have something to review tomorrow.
It looks good, but the implementation should not be Serilog-specific.
FilePath should also allow an absolute path (in case logs are outside the web root, which is more secure) and not have a Serilog-based default value (probably no default at all). When FilePath is relative, would that be relative to IWebHostEnvironment.WebRootPath or something else?
Must FilePath always point to a single file, or could it be a directory too, to support rotation? See https://docs.spring.io/spring-boot/reference/features/logging.html#features.logging.file-rotation. If so, how would the actuator know which file to return? It may be worth checking how this works in Spring.
Will the implementation support the Range HTTP header for efficiency?
@bart-vmware thanks for the notes.
I was originally planning on making FilePath relative to the application's working directory. I'd prefer not have the files inside the IWebHostEnvironment.WebRootPath as those files could be getting served for a web application, which may also be secured differently than the management endpoints.
I agree with the no default at all for the FilePath.
I would say FilePath must point to a single file as this is just the file that the actuator serves. I would suggest we rely on the app using this feature to configure their logging provider to configure their rotation to have some form of a current log and then archive log files.
Spring supports this by providing easier integration for a specific framework (Logback) and requires the app developer to manually configure rotation themselves for all other frameworks. This was mentioned in your link about the file rotation. I leaned towards Serilog as that's the other logging provider Steeltoe supports for Dynamic logging configuration. I don't have any experience configuring one of the built in logging providers to write to a file, but would be inclined to using one of those if they can be configured for file output.
The implementation will support the Range HTTP header for efficiency, as well as compatibility with the Logfile actuator in Spring Boot's API.
So the new settings would be:
| Key | Description | Default |
|---|---|---|
| Enabled | Whether the endpoint is enabled | true |
| ID | The unique ID of the endpoint | logfile |
| Path | The relative path at which the endpoint is exposed | logfile |
| RequiredPermissions | Permissions required to access the endpoint, when running on Cloud Foundry | Restricted |
| AllowedVerbs | An array of HTTP verbs the endpoint is exposed at. | GET |
| FilePath | The path to the log file that will be exposed. If relative, will be relative to the applications working directory. |
Looking forward to your thoughts.
An additional note: When configuring Spring's logging to just a directory, Spring uses a default log file name of spring.log. https://docs.spring.io/spring-boot/reference/features/logging.html#features.logging.file-output.
The logfile actuator in Spring seems to get a lot of its configuration from the actual logging configuration. The way to get the endpoint exposed is just configuring the logger and then adding "logfile" to be included in the endpoints web exposure:
spring:
application:
name: Sample Logging Application
management:
endpoints:
web:
exposure:
include: "logfile"
logging:
file:
path: ./logs/
I was originally planning on making FilePath relative to the application's working directory.
Looking at how existing logging frameworks resolve a relative path, we found the following (not entirely sure):
- Serilog: uses the current directory
- log4net: uses the directory where the app binary resides
- NLog: uses the directory where the app binary resides
Because the current directory isn't stable, I think Assembly.GetEntryAssembly would be more reliable.
I would say FilePath must point to a single file as this is just the file that the actuator serves.
Sounds good.
I don't have any experience configuring one of the built in logging providers to write to a file
As far as I know, the built-in providers don't support that.
Ok, that makes sense. I'll get started on a first pass that uses the Assembly.GetEntryAssembly to get a PR to continue the discussion.
@tscrypter i would like to suggest to allow filePath to point to a directory like spring boot and the api returns the most recently modified log file in that directory.
We could potentially even offer a http://localhost:8080/actuator/logfile/{{filename}}
@tscrypter i would like to suggest to allow filePath to point to a directory like spring boot and the api returns the most recently modified log file in that directory. We could potentially even offer a
http://localhost:8080/actuator/logfile/{{filename}}
This is an interesting idea but does not appear (from the docs anyway) to be supported in Spring. Some investigation would make sense, but I would say it is definitely not required for the current PR
My understanding reading the spec is that spring expects the file to be named spring.log hence why the actuator uses the directory path as per the sample above. Hence I am wanting to make the file Path setting as usable as possible and not lock user into fixed naming.
If we are wanting to retain the ability to specify the full file path, could we change the file search order to be the following:
- Get a single file which matches the file path
- Get all files which matches the file path (glob) and returns most recently modified file
- Get all files in directory specified by the file path (glob) and returns most recently modified file
I agree that the additional endpoint would come later and be better tracked via a separate issue