31

Spring Boot Actuator provides several endpoints to monitor an application as:

/metrics
/beans
/health
...

Checking the endpoints with:

curl http://localhost:8080/metrics

results in:

{"counter.status.200.env":1,"counter.status.200.health":1,"counter.status.200.info":2,"counter.status.200.metrics":2,"gauge.response.env":5.0,"gauge.response.health":22.0,"gauge.response.info":1.0,"gauge.response.metrics":1.0,"mem":1030144,"mem.free":56118,"processors":8,"uptime":5108095,"instance.uptime":5102906,"heap.committed":1030144,"heap.init":262144,"heap.used":974031,"heap":3728384,"threads.peak":81,"threads.daemon":21,"threads":77,"classes":8854,"classes.loaded":8860,"classes.unloaded":6,"gc.ps_scavenge.count":119,"gc.ps_scavenge.time":7223,"gc.ps_marksweep.count":12,"gc.ps_marksweep.time":17573}

This is fine for machine consumption but hard to read by humans.

I'd like to format (i.e. pretty print) the JSON output of the Spring Boot Actuator endpoints to make them easier to read by operations personel.

Something like:

{
  "counter.status.200.env":1,
  "counter.status.200.health":1,
  "counter.status.200.info":2,
  "counter.status.200.metrics":2,
  "gauge.response.env":5.0,
  "gauge.response.health":22.0,
  "gauge.response.info":1.0,
  ...
}

I tried setting

http.mappers.json-pretty-print=true 

but this setting didn't affect the Actuator output.

Is there a configuration to enable pretty print of the Spring Boot Actuator JSON output?

UPDATE:

The official sample works for me.

It's important to follow the comments from @DaveSyer: the property to set is

http.mappers.jsonPrettyPrint=true

Investigation is still under way.

In the meantime I use the the json pretty print command line as workaround:

Install jsonpp (e.g. for OS X):

brew install jsonpp

Then pipe the curl output trough jsonpp which formats the json file on the fly:

curl http://localhost:8080/metrics | jsonpp

Results in:

{
  "counter.status.200.env": 1,
  "counter.status.200.health": 1,
  "counter.status.200.info": 2,
  "counter.status.200.metrics": 2,
  ...
}

16 Answers16

60

As per http://docs.spring.io/spring-boot/docs/current/reference/html/howto-spring-mvc.html#howto-customize-the-jackson-objectmapper, the official way to enable pretty print with Jackson in Spring Boot (1.2.2 at least) is to set the following property:

 # Pretty-print JSON responses
 spring.jackson.serialization.indent_output=true
Bertrand Renuart
  • 1,608
  • 17
  • 24
  • It worked for me, altought STS gives this error: "Expecting com.fasterxml.jackson.databind.SerializationFeature[WRAP_ROOT_VALUE, INDENT_OUTPUT, FAIL_ON_EMPTY_BEANS, FAIL_ON_SELF_REFERENCES, ...]" – Darko Romanov Jul 03 '17 at 09:55
  • The pretty printer is turned on based on 3 checks (a && b && c), only this one can be turned `false` by configuration... somehow hard to find. – WesternGun Aug 28 '18 at 15:08
19

For Spring Boot 1.5.1 I have in my YML file:

spring:
  jackson:
    serialization:
      INDENT_OUTPUT: true

@BertrandRenuart answer was the closest, but by IDE did not see indent_output as correct.

Witold Kaczurba
  • 9,845
  • 3
  • 58
  • 67
10

The "http.mappers" property works for me but I think you might need it camel cased ("jsonPrettyPrint").

Dave Syer
  • 56,583
  • 10
  • 155
  • 143
  • Thanks! After changing to `http.mappers.jsonPrettyPrint=true` the setter in `HttpMapperProperties` get's called but the output isn't affected (There might be a documentation issue in http://docs.spring.io/spring-boot/docs/1.1.3.RELEASE/reference/htmlsingle/ it states `http.mappers.json-pretty-print`). I might still be missing some other config... – Bernhard Woditschka Jul 01 '14 at 07:15
  • Like I said, it works for me. If that setting isn't applied I suspect there may be something else in your app switching it off (e.g. a custom `ObjectMapper`). – Dave Syer Jul 01 '14 at 07:24
  • Tracing the application initialisation showed that 7 instances of `MappingJackson2HttpMessageConverter` get created and only one of them is configured with prettyPrint() – Bernhard Woditschka Jul 01 '14 at 08:16
  • You're probably going to have to share some code to get to the bottom if that. (Like I said, it woks for me.) – Dave Syer Jul 01 '14 at 08:17
  • I'll try prepare a small project to reproduce the behaviour and post it here – Bernhard Woditschka Jul 01 '14 at 08:21
  • 1
    Thanks, adding below for yaml configuration worked
    `http.mappers: jsonPrettyPrint: true`
    – Hussain Pirosha Jan 08 '15 at 07:14
  • I had the `@EnableWebMVC` annotation on an exception handler, which screws things up. After removing that, the `jsonPrettyPrint` property value was obeyed. – Jasper Blues Oct 25 '15 at 11:31
7

Do the following:

@Configuration
public class JacksonConfig {

    @Autowired
    private ObjectMapper objectMapper; //reuse the pre-configured mapper


    @PostConstruct
    public void setup() {
        objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
        //whatever else you need
    }


}

This works because Spring Boot uses an ObjectMapper bean to perform all the JSON related operations.

Note however that this configuration will pretty print all JSON outputs, not just the actuator related stuff.

UPDATE

The answer from @DaveSyer is obviously better! I hadn't found the HttpMapperProperties object which is used to configure Jackson. This is it's Javadoc

geoand
  • 60,071
  • 24
  • 172
  • 190
6

Actually I wanted to do the same. But then I asked: why? To debug my service better which comes with a small performance penalty.

Just use a browser extension, like this one :) to get a view like this one

enter image description here

Alex
  • 8,245
  • 8
  • 46
  • 55
  • Note: Not all JSON browser extensions work the same. I was using JSONView, and it was not formatting the Actuator output even though it worked for everything else in the past. The JSON Formatter extension recommended here does work for me. – Domenic Schiera May 12 '23 at 19:13
4

With spring-boot 1.2.6, you need to use:

spring.jackson.serialization.INDENT_OUTPUT=true

From my log when using the old http.mappers.*:

http.mappers.json-pretty-print is deprecated. If you are using Jackson, spring.jackson.serialization.INDENT_OUTPUT=true should be used instead.
Hakan
  • 537
  • 4
  • 13
3

I use Python's commonly installed json.tool module:

curl --silent http://localhost:8080/metrics | python -mjson.tool
Samuli Pahaoja
  • 2,660
  • 3
  • 24
  • 32
  • I also found that its the best option. `jq` or `python -m simplejson.tool` can be used as alternative pretty printer. In console processing with `pygmentize -l json` can be useful. All tools are available in Cygwin/Brew/Deb/RPM. – gavenkoa Feb 19 '17 at 11:08
3

If you're using gson serialization with Spring, then none of the other answers will work for you. You'll have to use this configuration option:

spring.gson.pretty-printing=true

Confirmed working with Spring Boot as of version 2.0.3.Release.

forresthopkinsa
  • 1,339
  • 1
  • 24
  • 29
2

I use jq for pretty printing JSON as well as filtering it. It's basically sed for JSON. On the mac, it can be installed with homebrew. (https://stedolan.github.io/jq/)

curl http://localhost:8080/metrics | jq 
gregory
  • 10,969
  • 2
  • 30
  • 42
2

Spring Boot Actuator uses its own isolated ObjectMapper instance by default in which indent-output is disabled. To enable pretty-print of actuator output, you must set the following properties:

spring.jackson.serialization.indent-output=true
management.endpoints.jackson.isolated-object-mapper=false
1

Instead of using curl I like to use httpie as a http command line client:

http http://localhost:8080/metrics

This would already format and syntax highlight the json response without having to pipe the output into another command. Also the command syntax is a bit more human friendly.

Seakayone
  • 610
  • 5
  • 11
0

Unfortunately, the application property

spring.jackson.serialization.INDENT_OUTPUT

did not work for me (spring boot versions 1.2.6 to 1.4.0.RELEASE). Instead, in my extension of WebMvcConfigurerAdapter, I've overridden configureMessageConverters() and added my own Jackson2ObjectMapperBuilder:

@Configuration
@EnableWebMvc
public class WebMvcConfig extends WebMvcConfigurerAdapter {
   ...
    private MappingJackson2HttpMessageConverter jacksonMessageConverter() {
        Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder()
                .featuresToDisable(SerializationFeature.FAIL_ON_EMPTY_BEANS,
                        SerializationFeature.WRITE_CHAR_ARRAYS_AS_JSON_ARRAYS)
                .featuresToEnable(SerializationFeature.INDENT_OUTPUT).modulesToInstall(hibernate4Module());
        // can use this instead of featuresToEnable(...)
        builder.indentOutput(true);
        return new MappingJackson2HttpMessageConverter(builder.build());
    }


    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.add(jacksonMessageConverter());
        super.configureMessageConverters(converters);
    }

   ...

}

That seem to do the trick for me on Spring boot 1.4.0.RELEASE and my actuator output is now pretty printed (along with every other json output)

Tom Silverman
  • 634
  • 1
  • 8
  • 7
0

Here is my Emacs function to retrieve Spring Actuator Json from endpoints:

(defvar my/spring-actuator-server-history nil)
(defvar my/spring-actuator-last-server "http://localhost:8080")
(defvar my/spring-actuator-path-history nil)
(defvar my/spring-actuator-path-completion
  '("actuator" "auditevents" "autoconfig" "beans" "configprops" "dump" "env" "flyway" "health" "heapdump"
    "info" "jolokia" "liquibase" "logfile" "loggers" "mappings" "metrics" "shutdown" "trace")))

(defun my/spring-actuator (server path)
  (interactive (list (read-string "Server: " my/spring-actuator-last-server 'my/spring-actuator-server-history)
                     (completing-read "Path: " my/spring-actuator-path-completion nil nil "" 'my/spring-actuator-path-history)))
  (setq my/spring-actuator-last-server server)
  (let ( (bufname (format "actuator: %s" path)) )
    (when (get-buffer bufname)
      (kill-buffer bufname))
    (switch-to-buffer (url-retrieve-synchronously (format "%s/%s" server path)))
    (rename-buffer bufname)
    (goto-char (point-min))
    (re-search-forward "^$" nil 'move)
    (forward-char)
    (delete-region (point-min) (point))
    (json-pretty-print-buffer)
    (json-mode) ))

If you don't like dependency on external json-mode library replace it with js-mode.

gavenkoa
  • 45,285
  • 19
  • 251
  • 303
0

In case somebody with Spring Boot 2 (2.1.1 in my case) stumbles over this question as I did: We faced the same problem, and none of the answers helped for 2.1.1.

So what we did was to replace the existing endpoint (health in our case) with a new one. I described it at the end of this answer. And yes, this limits our solution to this single endpoint, but on the other hand it has the advantage of being able to format the output in any way you want - including pretty print JSON, but also output styled HTML if requested (by a service technician in a browser in our case). Note the produces attribute of @ReadOperation to achieve that.

crusy
  • 1,424
  • 2
  • 25
  • 54
0

This is the latest as of 12/27/2022. The below works. -For application.yml config.

spring:
  jackson:
    serialization:
      indent-output: true

But the above config won't work, if you implement WebMvcConfigurer class. In that case, override like below to make it work.

@Override
public void extendMessageConverters( List<HttpMessageConverter<?>> converters ) {
    for ( HttpMessageConverter<?> converter : converters ) {
        if ( converter instanceof MappingJackson2HttpMessageConverter) {
            MappingJackson2HttpMessageConverter jacksonConverter = (MappingJackson2HttpMessageConverter) converter;
            jacksonConverter.setPrettyPrint( true );
        }
    }
}   
raman20
  • 11
  • 3
-1

this not working

spring.jackson.serialization.INDENT_OUTPUT=true

this is working spring.jackson.serialization.indent-output=true

tenlee
  • 1
  • 2