2

I would like to make all property placeholder and their resolved values of a running Spring (Boot) application available for process monitoring. In the first step this could be just by writing them to the logs or by creating a 'resolved.properties' file similar to the application.pid file. All properties where property placeholder are used (implicit/explicit) should be considered.

Motivation: It is usually hard during operation to know the values of resolved properties. System properties or command line arguments are "visible" but e.g. hidden default values in the code (like @Value("${timeout:30000}")) are hard to find out. I would like to be able to answer the question "How does the configuration of the running application looks like?" in a generic way that I can use in all of my spring applications.

I know about the Spring Boot Actuator /configprops endpoint, but this only includes @ConfigurationProperties. I would like to get a list of all properties where placeholder are used.

The requirement does not seem to be new (see here or here) but I wonder if there is an appropriate (bootiful) way nowadays.

Community
  • 1
  • 1
FrVaBe
  • 47,963
  • 16
  • 124
  • 157
  • There isn't. There currently is no way to list all the values for properties over all the property sources. Also in the case of for instance Spring Cloud Config that wouldn't add anything as properties could change during runtime. – M. Deinum Sep 05 '16 at 12:18
  • @M. Deinum Thanks. I do not think that it would not add anything as my configuration does not change during runtime. The function is provided in Boot with the `configprops` endpoint but limited to `@ConfigurationProperties`. It would be great if this limitation would go away and if Spring would provide access to all placeholder and their (current) values. – FrVaBe Sep 05 '16 at 12:23
  • There is no list of placeholders and the `PropertySources` abstraction doesn't provide such a thing. I'm not saying it wouldn't be great but there currently isn't... – M. Deinum Sep 05 '16 at 12:24
  • @M. Deinum Don't hesitate to provide it as answer. If that is how it is - I will accept it (but I will wait a while...) ;-) – FrVaBe Sep 05 '16 at 12:27

2 Answers2

3

There is (currently) no way to obtain all the properties in the Environment abstraction. This is intentional as can be read here. This is also why it isn't possible to obtain all the values used for resolution.

The values and resolutions are logged at runtime telling which key was resolved from where at runtime. But that logging is quite verbose and logged each time a StringValueResolver is used.

You might get a partial result by providing your own customized PropertySourcesPlaceholderConfigurer which maintains a collection of resolved key/value pairs. But not every resolution uses the PropertySourcesPlaceholderConfigurer some directly use a StringValueResolver implementation bypassing the PropertySourcesPlaceholderConfigurer.

M. Deinum
  • 115,695
  • 22
  • 220
  • 224
  • Thanks - especially for the very useful link to the background information. The provided solution from @Phil Webb seems to cover the information I am looking for except for properties with default value declarations. – FrVaBe Sep 05 '16 at 13:36
  • The issue is you get ALL the properties. So if one property is defined in your `application.properties` and as system or command line property you would get both values, not knowing which was actually being used. The same applies for `application-.properties` both the ones from `application.properties` and overriden ones will be shown. – M. Deinum Sep 05 '16 at 13:43
  • Very useful hint. Astonishing that Spring makes it that difficult in this use case. – FrVaBe Sep 05 '16 at 14:31
  • There is no way of knowing it. Placeholders are resolved when needed and it can change in between passed. Sometimes very early on in the proces only system en environment properties are available. Later on property files, jndi entries and servlet context params could change the resolution of certain values. Next to that not every possible property source is actual listable. There is no way to obtain all entries from JNDI for instance. – M. Deinum Sep 06 '16 at 08:44
0

It doesn't cover all your needs (ie: properties from all files, default values, application arguments, etc.). I'll still keep the answer for other readers/future reference.

Spring Boot's Actuator /env endpoint

You may use the /env endpoint. It lists a bunch of stuff but it also includes the content of application.properties (near the end):

applicationConfig: [classpath:/application.properties]={myproperty=blah, server.port=8080}
alexbt
  • 16,415
  • 6
  • 78
  • 87
  • Thanks. Unfortunately this does not list the properties from all locations (all files, default values, application arguments, etc.) – FrVaBe Sep 05 '16 at 13:07
  • Oh ok, I'll update the answer to say that it doesn't cover everything, but leave it for future references – alexbt Sep 05 '16 at 13:10