2

我有一个 SpringBoot 应用程序,它使用千分尺打印出应用程序指标。

我的 pom.xml 有:

<dependency>
    <groupId>io.micrometer</groupId>
    <artifactId>micrometer-core</artifactId>
    <version>1.1.3</version>
</dependency>

我的配置类是:

@Configuration
public class CoreConfiguration {

    public static final String USER_REQUEST_CHANNEL = "userRequestChannel";
    public static final String USER_RESPONSE_CHANNEL = "userResponseChannel";
    public static final String MDC_ADD = "add";
    public static final String DONE_CHANNEL = "nullChannel";
    public static final String ADMIN_REQUEST_CHANNEL = "adminRequestChannel";
    public static final String ADMIN_RESPONSE_CHANNEL = "adminResponseChannel";
    public static final String SUPPORT_COMPLETED_CHANNEL = "supportCompletedChannel";
    public static final String SUPPORT_RUNNING_CHANNEL = "nullChannel";
    public static final String SUPPORT_ERROR_CHANNEL = "nullChannel";

    @Bean(name = USER_REQUEST_CHANNEL)
    public MessageChannel oAuthRequestChannel() {
        return MessageChannels.direct().get();
    }

    @Bean(name = USER_RESPONSE_CHANNEL)
    public MessageChannel oAuthResponseChannel() {
        return MessageChannels.direct().get();
    }

    @Bean(name = FIRST_TRADE_CHANNEL)
    public MessageChannel firstTradeChannel() {
        return MessageChannels.direct().get();
    }

    @Bean(name = ADMIN_REQUEST_CHANNEL)
    public MessageChannel instructionExecutionRequestChannel() {
        return MessageChannels.direct().get();
    }

    @Bean(name = ADMIN_RESPONSE_CHANNEL)
    public MessageChannel instructionExecutionResponseChannel() {
        return MessageChannels.direct().get();
    }

    @Bean(name = SUPPORT_COMPLETED_CHANNEL)
    public MessageChannel groupExecutionCompletedChannel() {
        return MessageChannels.direct().get();
    }

    /**
     * Turn on the Micrometer log file metrics.
     *
     * @return
     */
    @Bean
    public LoggingMeterRegistry loggingMeterRegistry(@Value("${micrometer.log.minutes}") long minutes) {
        LoggingRegistryConfig config = new LoggingRegistryConfig() {
            @Override
            public String get(String s) {
                return null;
            }

            @Override
            public Duration step() {
                return Duration.ofMinutes(minutes);
            }
        };
        return LoggingMeterRegistry.builder(config).build();
    }
}

课堂使用:

public IntegrationFlow processRequest(HttpRequest request) {
    return IntegrationFlows.from(INPUT_CHANNEL)
            .enrichHeader(m -> m.headerExpression(REQUEST_ID,"payload.message.headers." + REQUEST_ID))
            .log(LoggingHandler.Level.DEBUG, CoreConfiguration.class.getName(), m -> {
                Throwable t = (Throwable) m.getPayload();
                return throwableToString(t);})
            .get();
}

我看到写入我的日志文件的指标输出为:

2019-02-25 14:40:23,337 | 信息 | [记录指标发布者] | [meter.core.instrument.logging.LoggingMeterRegistry] | MY_SAMPLE_APP | 用户 ID = [] | jvm.memory.max{area=heap,id=PS Survivor Space} value=12.5 MiB

如何以 JSON 格式注销?

我需要的:

{
"ts": "2019-02-25 14:40:23,337" ,
"level" : "INFO",
"className" : "meter.core.instrument.logging.LoggingMeterRegistry",
"appName" : "MY_SAMPLE_APP",
"userId" : "",
"metric" : 
        {"metricType": "jvm.memory.max",
         "area":"heap",
         "id":"PS Survivor Space",
         "value":"12.5 MiB"
         }
}

根据乔恩的回答用代码更新问题。@Jon,您认为下面的代码正确吗?我已经实现了一个扩展 LoggingMeterRegistry 的自定义 Meter Registry。

LoggingMeterRegistry 和 CustomMeterRegistry 的唯一区别是我的自定义类打印出 ID=

在 LoggingMeterRegistry 中: this.loggingSink.accept(print.id() + " throughput=" + print.rate(count));

在 CustomMeterRegistry 中: this.loggingSink.accept("ID=" + print.id() + " throughput=" + print.rate(count));

完整代码:

public abstract class SplunkMeterRegistry extends LoggingMeterRegistry {
@Override
protected void publish() {
{
    if (this.config.enabled()) {
        this.getMeters().stream().sorted((m1, m2) -> {
            int typeComp = m1.getId().getType().compareTo(m2.getId().getType());
            return typeComp == 0 ? m1.getId().getName().compareTo(m2.getId().getName()) : typeComp;
        }).forEach((m) -> {
            LoggingMeterRegistry.Printer print = new LoggingMeterRegistry.Printer(m);
            m.use((gauge) -> {
                this.loggingSink.accept("ID=" + print.id() + " value=" + print.value(gauge.value()));
            }, (counter) -> {
                double count = counter.count();
                if (this.config.logInactive() || count != 0.0D) {
                    this.loggingSink.accept("ID=" + print.id() + " throughput=" + print.rate(count));
                }
            }, (timer) -> {
                HistogramSnapshot snapshot = timer.takeSnapshot();
                long count = snapshot.count();
                if (this.config.logInactive() || count != 0L) {
                    this.loggingSink.accept("ID=" + print.id() + " throughput=" + print.unitlessRate((double)count) + " mean=" + print.time(snapshot.mean(this.getBaseTimeUnit())) + " max=" + print.time(snapshot.max(this.getBaseTimeUnit())));
                }
            }, (summary) -> {
                HistogramSnapshot snapshot = summary.takeSnapshot();
                long count = snapshot.count();
                if (this.config.logInactive() || count != 0L) {
                    this.loggingSink.accept("ID=" + print.id() + " throughput=" + print.unitlessRate((double)count) + " mean=" + print.value(snapshot.mean()) + " max=" + print.value(snapshot.max()));
                }
            }, (longTaskTimer) -> {
                int activeTasks = longTaskTimer.activeTasks();
                if (this.config.logInactive() || activeTasks != 0) {
                    this.loggingSink.accept("ID=" + print.id() + " active=" + print.value((double)activeTasks) + " duration=" + print.time(longTaskTimer.duration(this.getBaseTimeUnit())));
                }
            }, (timeGauge) -> {
                double value = timeGauge.value(this.getBaseTimeUnit());
                if (this.config.logInactive() || value != 0.0D) {
                    this.loggingSink.accept("ID=" + print.id() + " value=" + print.time(value));
                }
            }, (counter) -> {
                double count = counter.count();
                if (this.config.logInactive() || count != 0.0D) {
                    this.loggingSink.accept("ID=" + print.id() + " throughput=" + print.rate(count));
                }
            }, (timer) -> {
                double count = timer.count();
                if (this.config.logInactive() || count != 0.0D) {
                    this.loggingSink.accept("ID=" + print.id() + " throughput=" + print.rate(count) + " mean=" + print.time(timer.mean(this.getBaseTimeUnit())));
                }
            }, (meter) -> {
                this.loggingSink.accept("ID=" + print.id() + StreamSupport.stream(meter.measure().spliterator(), false).map((ms) -> {
                    return ms.getStatistic().getTagValueRepresentation() + "=" + DoubleFormat.decimalOrNan(ms.getValue());
                }));
            });
        });
    }

}
}

}

4

1 回答 1

1

您必须实现一个 custom MeterRegistry,可能LoggingMeterRegistry用作参考,以您想要的格式序列化数据。实际上,基于推送的MeterRegistry实现只是针对不同消费者的不同序列化格式。

于 2019-02-28T14:49:30.683 回答