fastjson序列化導致prometheus返回監控數據格式錯亂


在springboot 中集成prometheus的監控時遇見問題。
因為項目里在StaticResourceConfig配置了fastjson 序列化,導致prometheus接口返回數據被轉化為json格式,無法正常展示
正常情況格式應為這種

實際返回了這種

StaticResourceConfig 配置如下:

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        for (HttpMessageConverter<?> converter : converters) {
            if (converter instanceof MappingJackson2HttpMessageConverter) {
                converters.remove(converter);
            }
        }
        converters.add(new ByteArrayHttpMessageConverter());
        converters.add(getFastJsonConverter());
    }

    private FastJsonHttpMessageConverter getFastJsonConverter() {
        FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
        List<MediaType> supportedMediaTypes = new ArrayList<>();
        //提供對admin的類型支持mediaType
        MediaType mediaType = MediaType.valueOf("application/vnd.spring-boot.actuator.v2+json");
        supportedMediaTypes.add(mediaType);
        supportedMediaTypes.add(MediaType.ALL);
        converter.setSupportedMediaTypes(supportedMediaTypes);
        FastJsonConfig fastJsonConfig = new FastJsonConfig();
        fastJsonConfig.setSerializerFeatures(SerializerFeature.WriteDateUseDateFormat,
                SerializerFeature.WriteNullStringAsEmpty,
                SerializerFeature.WriteMapNullValue,
                SerializerFeature.DisableCircularReferenceDetect);
        //日期格式化
        fastJsonConfig.setDateFormat("yyyy-MM-dd HH:mm:ss");
        ParserConfig parserConfig = ParserConfig.getGlobalInstance();
        parserConfig.setSafeMode(true);
        fastJsonConfig.setParserConfig(parserConfig);
        converter.setFastJsonConfig(fastJsonConfig);

        return converter;
    }

解決辦法

通過增加一層轉發,調用監控接口獲取到數據,然后反序列化為原來的格式,然后通過response.write方式返回監控結果。
因為采用response.write的方式,不會被spring mvc的HttpMessageConverter所攔截,所以可以直接返回plain/text格式的數據

package com.yuanian.monitor;

import com.alibaba.fastjson.JSON;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletResponse;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.net.URISyntaxException;

/**
 * @author liujy
 * @since Wed Feb 24 17:55:16 CST 2021
 */
@RestController
@RequestMapping("prometheus")
public class PrometheusController {
    @Value("${server.servlet.context-path}")
    private String contextPath;
    @Value("${server.port}")
    private Integer port;

    @GetMapping(path = "/metrics", produces = MediaType.TEXT_PLAIN_VALUE)
    public void healthz(HttpServletResponse response) throws URISyntaxException {
        RestTemplate restTemplate = new RestTemplate();
        StringBuilder prometheusUrl = new StringBuilder("http://127.0.0.1:");
        prometheusUrl.append(port);
        prometheusUrl.append(contextPath);
        prometheusUrl.append("/actuator/prometheus");

        ResponseEntity<String> responseEntity = restTemplate.getForEntity(prometheusUrl.toString(), String.class);
        String body = responseEntity.getBody();
        String s = JSON.parseObject(body, String.class);

        try (BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream())) {
            bos.write(s.getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM