logging.file=logs/app.log
logging.file.max-history=20
logging.file.max-size=50MB
how to config these properties in yml file
#log
logging:
file: // how to config
max-history: 30
max-size: 50MB
Thanks for getting in touch, but it feels like this is a question that would be better suited to Stack Overflow. As mentioned in the guidelines for contributing, we prefer to use GitHub issues only for bugs and enhancements. Feel free to update this issue with a link to the re-posted question (so that other people can find it) or add some more details if you feel this is a genuine bug.
yaml file can not support config for logging.file=xx.log with logging.file.max-history=20
@wilkinsona
in application.properties
we can use this:
logging.file=logs/app.log
logging.file.max-history=20
logging.file.max-size=50MB
bug in application.yml can not set these three properties in same time
If you'd like us to spend some time investigating, you're going to have to spend some time to make sure that we're investigating the problem that you're seeing. As I already asked in #12522, please provide a minimal, complete, and verifiable example and we can re-open this issue and investigate.
I think I finally understand the issue here. A sample would have been very useful. As would have including the full stack trace.
Given the following YAML:
logging:
file: logs/app.log
max-history: 20
max-size: 50MB
The following exception is raised:
java.lang.IllegalStateException: Failed to load property source from location 'classpath:/application.yml'
at org.springframework.boot.context.config.ConfigFileApplicationListener$Loader.load(ConfigFileApplicationListener.java:481)
at org.springframework.boot.context.config.ConfigFileApplicationListener$Loader.loadForFileExtension(ConfigFileApplicationListener.java:446)
at org.springframework.boot.context.config.ConfigFileApplicationListener$Loader.load(ConfigFileApplicationListener.java:419)
at org.springframework.boot.context.config.ConfigFileApplicationListener$Loader.load(ConfigFileApplicationListener.java:329)
at org.springframework.boot.context.config.ConfigFileApplicationListener.addPropertySources(ConfigFileApplicationListener.java:205)
at org.springframework.boot.context.config.ConfigFileApplicationListener.postProcessEnvironment(ConfigFileApplicationListener.java:188)
at org.springframework.boot.context.config.ConfigFileApplicationListener.onApplicationEnvironmentPreparedEvent(ConfigFileApplicationListener.java:175)
at org.springframework.boot.context.config.ConfigFileApplicationListener.onApplicationEvent(ConfigFileApplicationListener.java:161)
at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172)
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:127)
at org.springframework.boot.context.event.EventPublishingRunListener.environmentPrepared(EventPublishingRunListener.java:74)
at org.springframework.boot.SpringApplicationRunListeners.environmentPrepared(SpringApplicationRunListeners.java:54)
at org.springframework.boot.SpringApplication.prepareEnvironment(SpringApplication.java:351)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:317)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1246)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1234)
at scratch.BindingApplication.main(BindingApplication.java:10)
Caused by: org.yaml.snakeyaml.scanner.ScannerException: mapping values are not allowed here
in 'reader', line 3, column 16:
max-history: 20
^
at org.yaml.snakeyaml.scanner.ScannerImpl.fetchValue(ScannerImpl.java:872)
at org.yaml.snakeyaml.scanner.ScannerImpl.fetchMoreTokens(ScannerImpl.java:360)
at org.yaml.snakeyaml.scanner.ScannerImpl.checkToken(ScannerImpl.java:226)
at org.yaml.snakeyaml.parser.ParserImpl$ParseBlockMappingKey.produce(ParserImpl.java:557)
at org.yaml.snakeyaml.parser.ParserImpl.peekEvent(ParserImpl.java:157)
at org.yaml.snakeyaml.parser.ParserImpl.checkEvent(ParserImpl.java:147)
at org.yaml.snakeyaml.composer.Composer.composeMappingNode(Composer.java:227)
at org.yaml.snakeyaml.composer.Composer.composeNode(Composer.java:154)
at org.yaml.snakeyaml.composer.Composer.composeValueNode(Composer.java:249)
at org.yaml.snakeyaml.composer.Composer.composeMappingChildren(Composer.java:240)
at org.yaml.snakeyaml.composer.Composer.composeMappingNode(Composer.java:228)
at org.yaml.snakeyaml.composer.Composer.composeNode(Composer.java:154)
at org.yaml.snakeyaml.composer.Composer.composeDocument(Composer.java:122)
at org.yaml.snakeyaml.composer.Composer.getNode(Composer.java:84)
at org.yaml.snakeyaml.constructor.BaseConstructor.getData(BaseConstructor.java:123)
at org.yaml.snakeyaml.Yaml$1.next(Yaml.java:547)
at org.springframework.beans.factory.config.YamlProcessor.process(YamlProcessor.java:161)
at org.springframework.beans.factory.config.YamlProcessor.process(YamlProcessor.java:139)
at org.springframework.boot.env.OriginTrackedYamlLoader.load(OriginTrackedYamlLoader.java:75)
at org.springframework.boot.env.YamlPropertySourceLoader.load(YamlPropertySourceLoader.java:49)
at org.springframework.boot.context.config.ConfigFileApplicationListener$Loader.load(ConfigFileApplicationListener.java:469)
... 18 common frames omitted
You can work around it by doing this:
logging.file: logs/app.log
logging:
file:
max-history: 20
max-size: 50MB
Since there's a workaround I don't think we should change things in 2.0. It is probably worth reviewing all properties in 2.1 to make sure things map to yaml nicely.
It's not the file that's the issue. It's the dash (-) in both max-history and max-size. They would work fine if they were maxHistory and maxSize.
Here is the error:
mapping values are not allowed here in 'reader', line 3, column 16:
max-history: 20
That's why the suggested workaround actually doesn't work.
It thinks that it's trying to map some values to a list like:
teams:
red:
- Player1
- Player2
blue:
- Player3
..but it's giving the error because it's seeing the dash and trying to build a list.
Since I can't specify those values I'm spewing endless logs like crazy.
@shutterstein I'm not following how the snippet of yaml you've pasted related to the issue above. My understanding is that a entry that starts with -
is treated as a list, but a entry with a -
in the middle is fine. I tried the work-around locally and it was fine. Can you share a sample that fails?
@philwebb The error specified above (which I was also experiencing) was coming from whichever of the max-history or max-size were specified first. I just gave the example because it seemed from the error message that it was thinking we were trying to specify a list or something along those lines.
As far as an example, I had virtually copied how you had done it and it still failed with the same error about "mapping values" and pointed at the "max-history" attribute (which was specified first in my yml file). Here was how I had it when it was still failing with the same error on max-history:
logging.file: logs/server.log
logging:
level:
root: info
file:
max-history: 10
max-size: 100MB
I did, however, get it to workaround properly for those two properties by specifying it similarly as you had done in the file specification:
logging.file.max-history: 10
logging.file.max-size: 100MB
So that has helped me workaround the issue now. Thanks!
@philwebb Honestly, there aren't that much properties that have this issue. Wouldn't it be a better idea to just consider renaming logging.file
to logging.file.name
, in which case, the resulting configuration would be:
logging.file.name=server.log
logging.file.max-history=10
logging.file.max-size=100MB
logging:
file:
name: server.log
max-history: 10
max-size: 100MB
See LogFile.java#L42
Other than logging.file
, the only other property that is affected by this would be logging.level
, like so:
logging:
level:
org:
springframework: ERROR <---- oops
orm: INFO
but I personally think that it's not as easy to read as something like this:
logging:
level:
org.springframework: ERROR
org.springframework.orm: INFO
I think that the logging.level
issue is understandable, but I don't think that a change should be made to support having a structure element (e.g. file
) support both a value and a substructure.
YAML is a superset of JSON, and with JSON, this logging.file
case would translate to trying to do the following:
{
"logging": {
"file": "server.log" { <---- a value and an array? that doesn't make sense
"max-history": "10",
"max-size": "100MB"
}
}
}
Clearly JSON doesn't support that, instead, the configuration would be expected to be like so:
{
"logging": {
"file": {
"name": "server.log",
"max-history": "10",
"max-size": "100MB"
}
}
}
Just my 2 cents
@TwinProduction Indeed, that's what I had in mind but this one slipped though the net for 2.1. I've assigned it to 2.2.x so that we get to it next time.
Hi, the comparison with json is a good point, even if it seems that yaml does allow it.
If you do decide to make that syntax illegal, may I advise to remove its use within spring then :
spring:
profiles: currentProfile
profiles.include: profileToInclude
Related: https://stackoverflow.com/questions/35372340/spring-profile-include-issue-with-yaml-file/53657492
@Chatom YAML is a superset of JSON, therefore there's nothing wrong with supporting some of its syntax.
As mentioned above, there's a need for supporting that syntax, here's an example (same example I gave above, but a bit more explicit):
logging:
level:
org.springframework: INFO
org.springframework.orm: INFO
If we do make the syntax completely illegal, then we'd have this:
logging:
level:
org:
springframework: INFO
orm: WARN <--- Syntax error
Because it would translate to something like this, which is invalid:
{
"logging": {
"level": {
"org": {
"springframework": "INFO" { <---- Syntax error
"orm": "WARN"
}
}
}
}
}
TL;DR: 1 key can only be assigned to 1 value, and some properties must have more than one value (e.g. in this case, JSON object and a String)
Honestly, this wouldn't be an issue if IDEs gave a syntax error for YAML when it should, but currently, most IDEs don't complain about things like this:
foo: bar
bar: foo
It should seriously be considered as a parsing error, because it breaks backward compatibility with JSON.
I think I finally understand the issue here. A sample would have been very useful. As would have including the full stack trace.
Given the following YAML:
logging: file: logs/app.log max-history: 20 max-size: 50MB
The following exception is raised:
java.lang.IllegalStateException: Failed to load property source from location 'classpath:/application.yml' at org.springframework.boot.context.config.ConfigFileApplicationListener$Loader.load(ConfigFileApplicationListener.java:481) at org.springframework.boot.context.config.ConfigFileApplicationListener$Loader.loadForFileExtension(ConfigFileApplicationListener.java:446) at org.springframework.boot.context.config.ConfigFileApplicationListener$Loader.load(ConfigFileApplicationListener.java:419) at org.springframework.boot.context.config.ConfigFileApplicationListener$Loader.load(ConfigFileApplicationListener.java:329) at org.springframework.boot.context.config.ConfigFileApplicationListener.addPropertySources(ConfigFileApplicationListener.java:205) at org.springframework.boot.context.config.ConfigFileApplicationListener.postProcessEnvironment(ConfigFileApplicationListener.java:188) at org.springframework.boot.context.config.ConfigFileApplicationListener.onApplicationEnvironmentPreparedEvent(ConfigFileApplicationListener.java:175) at org.springframework.boot.context.config.ConfigFileApplicationListener.onApplicationEvent(ConfigFileApplicationListener.java:161) at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172) at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165) at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139) at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:127) at org.springframework.boot.context.event.EventPublishingRunListener.environmentPrepared(EventPublishingRunListener.java:74) at org.springframework.boot.SpringApplicationRunListeners.environmentPrepared(SpringApplicationRunListeners.java:54) at org.springframework.boot.SpringApplication.prepareEnvironment(SpringApplication.java:351) at org.springframework.boot.SpringApplication.run(SpringApplication.java:317) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1246) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1234) at scratch.BindingApplication.main(BindingApplication.java:10) Caused by: org.yaml.snakeyaml.scanner.ScannerException: mapping values are not allowed here in 'reader', line 3, column 16: max-history: 20 ^ at org.yaml.snakeyaml.scanner.ScannerImpl.fetchValue(ScannerImpl.java:872) at org.yaml.snakeyaml.scanner.ScannerImpl.fetchMoreTokens(ScannerImpl.java:360) at org.yaml.snakeyaml.scanner.ScannerImpl.checkToken(ScannerImpl.java:226) at org.yaml.snakeyaml.parser.ParserImpl$ParseBlockMappingKey.produce(ParserImpl.java:557) at org.yaml.snakeyaml.parser.ParserImpl.peekEvent(ParserImpl.java:157) at org.yaml.snakeyaml.parser.ParserImpl.checkEvent(ParserImpl.java:147) at org.yaml.snakeyaml.composer.Composer.composeMappingNode(Composer.java:227) at org.yaml.snakeyaml.composer.Composer.composeNode(Composer.java:154) at org.yaml.snakeyaml.composer.Composer.composeValueNode(Composer.java:249) at org.yaml.snakeyaml.composer.Composer.composeMappingChildren(Composer.java:240) at org.yaml.snakeyaml.composer.Composer.composeMappingNode(Composer.java:228) at org.yaml.snakeyaml.composer.Composer.composeNode(Composer.java:154) at org.yaml.snakeyaml.composer.Composer.composeDocument(Composer.java:122) at org.yaml.snakeyaml.composer.Composer.getNode(Composer.java:84) at org.yaml.snakeyaml.constructor.BaseConstructor.getData(BaseConstructor.java:123) at org.yaml.snakeyaml.Yaml$1.next(Yaml.java:547) at org.springframework.beans.factory.config.YamlProcessor.process(YamlProcessor.java:161) at org.springframework.beans.factory.config.YamlProcessor.process(YamlProcessor.java:139) at org.springframework.boot.env.OriginTrackedYamlLoader.load(OriginTrackedYamlLoader.java:75) at org.springframework.boot.env.YamlPropertySourceLoader.load(YamlPropertySourceLoader.java:49) at org.springframework.boot.context.config.ConfigFileApplicationListener$Loader.load(ConfigFileApplicationListener.java:469) ... 18 common frames omitted
You can work around it by doing this:
logging.file: logs/app.log logging: file: max-history: 20 max-size: 50MB
No exception but no effect for springboot 1.5.6
When using the following YAML:
logging:
file: logs/app.log
max-history: 20
max-size: 50MB
It fails as described above with 1.5.6.
When using the following YAML:
logging.file: logs/app.log
logging:
max-history: 20
max-size: 50MB
The configuration takes effect and logs are written to logs/app.log
as expected.
@controlloli If you need any further guidance on how to use the workaround, please come and chat on Gitter or ask a question on Stack Overflow.
I couldn't find any other properties that can't be mapped in YAML. spring.profiles
when combined with spring.profiles.include/active
seems to be the only one and I don't think we should do anything about that till we decide how we want to handle include profiles in profile-specific YAML documents.
I'm in favor of closing this issue now that logging.file
has been renamed to logging.file.name
.
Most helpful comment
I think I finally understand the issue here. A sample would have been very useful. As would have including the full stack trace.
Given the following YAML:
The following exception is raised:
You can work around it by doing this: