下面列出了 io.netty.handler.codec.http2.Http2FrameWriter #io.micrometer.core.instrument.Timer 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@ApiOperation(value = "Sends a given array of messages to a road")
@ApiResponses({
@ApiResponse(code = 200, message = "Messages have been sent successfully.", response = StandardResponse.class),
@ApiResponse(code = 400, message = "Bad Request.", response = StandardResponse.class),
@ApiResponse(code = 404, message = "Road not found.", response = StandardResponse.class),
@ApiResponse(code = 422, message = "Road not enabled.", response = StandardResponse.class) })
@PreAuthorize("@onrampAuthorisation.isAuthorised(authentication,#roadName)")
@PostMapping(path = "/roads/{roadName}/messages")
public Iterable<StandardResponse> produce(@PathVariable String roadName, @RequestBody ArrayNode json)
throws UnknownRoadException, InterruptedException {
Timer.Sample sample = Timer.start(registry);
DistributionSummary.builder("onramp.request").tag("road", roadName).register(registry).record(json.size());
Onramp onramp = service.getOnramp(roadName).orElseThrow(() -> new UnknownRoadException(roadName));
if (!onramp.isAvailable()) {
throw new RoadUnavailableException(String.format("Road '%s' is disabled, could not send events.", roadName));
}
Iterable<StandardResponse> responses = sendMessages(onramp, json);
sample.stop(registry.timer("onramp.request.timer", "road", roadName));
return responses;
}
@DisplayName("autocloseable sample")
@ParameterizedTest(name = "when outcome is '{0}'")
@CsvSource({"success", "error"})
@Issue("#1425")
default void closeable(String outcome) {
MeterRegistry registry = new SimpleMeterRegistry();
try (Timer.ResourceSample sample = Timer.resource(registry, "requests")
.description("This is an operation")
.publishPercentileHistogram()) {
try {
if (outcome.equals("error")) {
throw new IllegalArgumentException("boom");
}
sample.tag("outcome", "success");
} catch (Throwable t) {
sample.tag("outcome", "error");
}
}
assertThat(registry.get("requests").tag("outcome", outcome).timer().count())
.isEqualTo(1);
}
@Test
public void givenTimer_whenWrapTasks_thenTimeRecorded() {
SimpleMeterRegistry registry = new SimpleMeterRegistry();
Timer timer = registry.timer("app.event");
timer.record(() -> {
try {
TimeUnit.MILLISECONDS.sleep(15);
} catch (InterruptedException ignored) {
}
});
timer.record(30, TimeUnit.MILLISECONDS);
assertTrue(2 == timer.count());
assertThat(timer.totalTime(TimeUnit.MILLISECONDS)).isBetween(40.0, 55.0);
}
@Test
public void testSimpleTimer() {
// Creating a simplify timer
final SkywalkingMeterRegistry registry = new SkywalkingMeterRegistry();
final Timer timer = registry.timer("test_simple_timer", "skywalking", "test");
// Check Skywalking type
Assert.assertTrue(timer instanceof SkywalkingTimer);
final List<MeterId.Tag> tags = Arrays.asList(new MeterId.Tag("skywalking", "test"));
// Multiple record data
timer.record(10, TimeUnit.MILLISECONDS);
timer.record(20, TimeUnit.MILLISECONDS);
timer.record(3, TimeUnit.MILLISECONDS);
// Check micrometer data
Assert.assertEquals(3, timer.count());
Assert.assertEquals(33d, timer.totalTime(TimeUnit.MILLISECONDS), 0.0);
Assert.assertEquals(20d, timer.max(TimeUnit.MILLISECONDS), 0.0);
// Check Skywalking data
assertCounter(Whitebox.getInternalState(timer, "counter"), "test_simple_timer_count", tags, 3d);
assertCounter(Whitebox.getInternalState(timer, "sum"), "test_simple_timer_sum", tags, 33d);
assertGauge(Whitebox.getInternalState(timer, "max"), "test_simple_timer_max", tags, 20d);
assertHistogramNull(Whitebox.getInternalState(timer, "histogram"));
}
/**
* Called after the resource method.
*/
@Override
public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext)
throws IOException {
Sample sample = (Sample) requestContext.getProperty(TIMING_SAMPLE);
if (sample != null) {
Timer timer = Timer
.builder("http.server.requests")
// no way to access the exception
.tag("exception", "")
.tag("outcome", computeOutcome(responseContext))
.tag("method", getMethod(requestContext))
.tag("status", getStatus(responseContext))
.tag("uri", getUri())
.publishPercentileHistogram()
.maximumExpectedValue(Duration.ofSeconds(10))
.register(registry);
sample.stop(timer);
}
}
@Test
public void shouldCountSuccessfulStart() {
// given
workspaceStopTime.put("id1", System.currentTimeMillis() - 60 * 1000);
// when
eventService.publish(
DtoFactory.newDto(WorkspaceStatusEvent.class)
.withPrevStatus(WorkspaceStatus.STOPPING)
.withStatus(WorkspaceStatus.STOPPED)
.withWorkspaceId("id1"));
// then
Timer t = registry.find("che.workspace.stop.time").tag("result", "success").timer();
Assert.assertEquals(t.count(), 1);
Assert.assertTrue(t.totalTime(TimeUnit.MILLISECONDS) >= 60 * 1000);
}
@Test
public void shouldAliasTimerLabel() {
MeterRegistry registry = new SimpleMeterRegistry();
BackendRegistries.registerMatchers(registry, ALL_LABELS, Collections.singletonList(new Match()
.setLabel("address")
.setType(MatchType.REGEX)
.setValue("addr1")
.setAlias("1")));
Timers timers = new Timers("my_timer", "", registry, Label.EB_ADDRESS);
timers.get("addr1").record(5, TimeUnit.MILLISECONDS);
timers.get("addr1").record(8, TimeUnit.MILLISECONDS);
timers.get("addr2").record(10, TimeUnit.MILLISECONDS);
Timer t = registry.find("my_timer").tags("address", "1").timer();
assertThat(t.count()).isEqualTo(2);
assertThat(t.totalTime(TimeUnit.MILLISECONDS)).isEqualTo(13);
t = registry.find("my_timer").tags("address", "addr1").timer();
assertThat(t).isNull();
t = registry.find("my_timer").tags("address", "addr2").timer();
assertThat(t.count()).isEqualTo(1);
assertThat(t.totalTime(TimeUnit.MILLISECONDS)).isEqualTo(10);
}
@Test
void shouldRecordErrorResponseMetric() {
driver.addExpectation(onRequestTo("/bar").withMethod(POST),
giveEmptyResponse().withStatus(503));
unit.post(URI.create("/bar"))
.dispatch(series(),
on(SUCCESSFUL).call(pass()))
.exceptionally(e -> null)
.join();
@Nullable final Timer timer = search().timer();
assertThat(timer, is(notNullValue()));
assertThat(timer.getId().getTag("http.method"), is("POST"));
assertThat(timer.getId().getTag("http.path"), is(""));
assertThat(timer.getId().getTag("http.status_code"), is("503"));
assertThat(timer.getId().getTag("peer.hostname"), is("localhost"));
assertThat(timer.getId().getTag("error.kind"), is("none"));
assertThat(timer.getId().getTag("client"), is("example"));
assertThat(timer.getId().getTag("test"), is("true"));
assertThat(timer.totalTime(NANOSECONDS), is(greaterThan(0.0)));
}
@Test
void timerMax() {
AtlasConfig atlasConfig = new AtlasConfig() {
@Override
public String get(String k) {
return null;
}
@Override
public Duration lwcStep() {
return step();
}
};
AtlasMeterRegistry registry = new AtlasMeterRegistry(atlasConfig, new MockClock());
Timer timer = registry.timer("timer");
timer.record(1, TimeUnit.SECONDS);
clock(registry).add(atlasConfig.step());
assertThat(timer.max(TimeUnit.MILLISECONDS)).isEqualTo(1000);
}
protected KeepAliveHandler(Channel channel, String name, Timer keepAliveTimer,
long idleTimeoutMillis, long pingIntervalMillis, long maxConnectionAgeMillis) {
this.channel = channel;
this.name = name;
this.keepAliveTimer = keepAliveTimer;
if (idleTimeoutMillis <= 0) {
connectionIdleTimeNanos = 0;
} else {
connectionIdleTimeNanos = TimeUnit.MILLISECONDS.toNanos(idleTimeoutMillis);
}
if (pingIntervalMillis <= 0) {
pingIdleTimeNanos = 0;
} else {
pingIdleTimeNanos = TimeUnit.MILLISECONDS.toNanos(pingIntervalMillis);
}
if (maxConnectionAgeMillis <= 0) {
maxConnectionAgeNanos = 0;
} else {
maxConnectionAgeNanos = TimeUnit.MILLISECONDS.toNanos(maxConnectionAgeMillis);
}
}
@Test
void histogramsContainLongMaxValue() {
MeterRegistry registry = new SimpleMeterRegistry();
Timer timer = Timer.builder("my.timer")
.serviceLevelObjectives(Duration.ofNanos(Long.MAX_VALUE))
.register(registry);
DistributionSummary distributionSummary = DistributionSummary.builder("my.distribution")
.serviceLevelObjectives(Double.POSITIVE_INFINITY)
.register(registry);
HistogramGauges distributionGauges = HistogramGauges.registerWithCommonFormat(distributionSummary, registry);
HistogramGauges timerGauges = HistogramGauges.registerWithCommonFormat(timer, registry);
assertThat(registry.get("my.distribution.histogram").tag("le", "+Inf").gauge()).isNotNull();
assertThat(registry.get("my.timer.histogram").tag("le", "+Inf").gauge()).isNotNull();
}
public final NumericQuery count(Function<Search, Search> search) {
return new Instant(name, tags, baseUnit, failedMessage, requires, search, s -> s.meters().stream()
.map(m -> {
if (m instanceof Counter) {
return ((Counter) m).count();
} else if (m instanceof Timer) {
return (double) ((Timer) m).count();
} else if (m instanceof FunctionTimer) {
return ((FunctionTimer) m).count();
} else if (m instanceof FunctionCounter) {
((FunctionCounter) m).count();
} else if (m instanceof LongTaskTimer) {
return (double) ((LongTaskTimer) m).activeTasks();
}
return Double.NaN;
})
.reduce(Double.NaN, SUM_OR_NAN)
);
}
private void configureHttp(ChannelPipeline p, @Nullable ProxiedAddresses proxiedAddresses) {
final long idleTimeoutMillis = config.idleTimeoutMillis();
final KeepAliveHandler keepAliveHandler;
if (idleTimeoutMillis > 0) {
final Timer keepAliveTimer = newKeepAliveTimer(H1C);
keepAliveHandler = new Http1ServerKeepAliveHandler(
p.channel(), keepAliveTimer, idleTimeoutMillis, config.maxConnectionAgeMillis());
} else {
keepAliveHandler = null;
}
final ServerHttp1ObjectEncoder responseEncoder = new ServerHttp1ObjectEncoder(
p.channel(), H1C, keepAliveHandler,
config.isDateHeaderEnabled(), config.isServerHeaderEnabled()
);
p.addLast(TrafficLoggingHandler.SERVER);
p.addLast(new Http2PrefaceOrHttpHandler(responseEncoder));
p.addLast(new HttpServerHandler(config, gracefulShutdownSupport, responseEncoder,
H1C, proxiedAddresses));
}
/**
* Creates a new delegating ServerCall that will wrap the given server call to collect metrics.
*
* @param delegate The original call to wrap.
* @param registry The registry to save the metrics to.
* @param responseCounter The counter for incoming responses.
* @param timerFunction A function that will return a timer for a given status code.
*/
public MetricCollectingServerCall(final ServerCall<Q, A> delegate, final MeterRegistry registry,
final Counter responseCounter,
final Function<Code, Timer> timerFunction) {
super(delegate);
this.responseCounter = responseCounter;
this.timerFunction = timerFunction;
this.timerSample = Timer.start(registry);
}
public final NumericQuery max(Function<Search, Search> search) {
return new Instant(name, tags, baseUnit, failedMessage, requires, search, s -> s.meters().stream()
.map(m -> {
if (m instanceof DistributionSummary) {
return ((DistributionSummary) m).max();
} else if (m instanceof Timer) {
return ((Timer) m).max(TimeUnit.NANOSECONDS);
} else if (m instanceof LongTaskTimer) {
return ((LongTaskTimer) m).max(TimeUnit.NANOSECONDS);
}
return Double.NaN;
})
.reduce(Double.NaN, MAX_OR_NAN)
);
}
@Test
@DisplayName("negative times are discarded by the Timer")
default void recordNegative(MeterRegistry registry) {
Timer t = registry.timer("myTimer");
t.record(-42, TimeUnit.MILLISECONDS);
assertAll(() -> assertEquals(0L, t.count()),
() -> assertEquals(0, t.totalTime(TimeUnit.NANOSECONDS), 1.0e-12));
}
@Test
public void noOnNextTimer() {
Mono<Integer> source = Mono.just(1)
.hide();
new MonoMetrics<>(source, registry)
.block();
Timer nextMeter = registry
.find(METER_ON_NEXT_DELAY)
.timer();
assertThat(nextMeter).isNull();
}
public static void main(String[] args) throws InterruptedException {
MeterRegistry registry = SampleRegistries.wavefront();
Timer t = null;
for (Integer i = 0; i < 80; i++) {
t = Timer.builder("my.timer")
.tag("index", i.toString())
// .publishPercentileHistogram()
.serviceLevelObjectives(Stream.of(1, 150, 300, 500, 900, 1000, 1200, 1500, 2000, 3000, 4000)
.map(Duration::ofMillis)
.toArray(Duration[]::new))
.publishPercentiles(0.95)
.percentilePrecision(1)
.register(registry);
}
// Breakpoint somewhere after the first couple outputs to test pause detection
// for (int i = 0; ; i = (i + 1) % 2000) {
// Thread.sleep(2);
// t.record(1, TimeUnit.MILLISECONDS);
// if (i == 1000) {
// t.takeSnapshot().outputSummary(System.out, 1e6);
// }
// }
Flux.never().blockLast();
}
static void recordOnError(Tags commonTags, MeterRegistry registry, Timer.Sample flowDuration, Throwable e) {
Timer timer = Timer.builder(METER_FLOW_DURATION)
.tags(commonTags.and(TAG_ON_ERROR))
.tag(TAG_KEY_EXCEPTION,
e.getClass()
.getName())
.description(
"Times the duration elapsed between a subscription and the onError termination of the sequence, with the exception name as a tag.")
.register(registry);
flowDuration.stop(timer);
}
@Override
public void recordDataReceivedTime(String uri, String method, Duration time) {
Timer dataReceivedTime = dataReceivedTimeCache.computeIfAbsent(new MeterKey(uri, null, method, null),
key -> filter(dataReceivedTimeBuilder.tags(URI, uri, METHOD, method)
.register(REGISTRY)));
if (dataReceivedTime != null) {
dataReceivedTime.record(time);
}
}
public static final void recordTime(String name, long timeElapsed, TimeUnit timeUnit, double[] percentiles,
Duration[] sla, String... tags) {
try {
Timer.builder(name).publishPercentiles(percentiles).sla(sla).publishPercentileHistogram()
.tags(MicrometerUtil.tags(tags)).register(registry()).record(timeElapsed, timeUnit);
} catch (Throwable e) {
LOGGER.warn(" recordTime error", e);
}
}
@Benchmark
public int sumTimedWithSample() {
Timer.Sample sample = Timer.start(registry);
int sum = sum();
sample.stop(timer);
return sum;
}
@Test
public void subscribeToCancelFuseable() throws InterruptedException {
Mono<String> source = Mono.delay(Duration.ofMillis(200))
.map(i -> "foo");
Disposable disposable = new MonoMetricsFuseable<>(source, registry).subscribe();
Thread.sleep(100);
disposable.dispose();
Timer stcCompleteTimer = registry.find(METER_FLOW_DURATION)
.tags(Tags.of(TAG_ON_COMPLETE))
.timer();
Timer stcErrorTimer = registry.find(METER_FLOW_DURATION)
.tags(Tags.of(TAG_ON_ERROR))
.timer();
Timer stcCancelTimer = registry.find(METER_FLOW_DURATION)
.tags(Tags.of(TAG_CANCEL))
.timer();
SoftAssertions.assertSoftly(softly -> {
softly.assertThat(stcCompleteTimer)
.as("subscribe to complete timer")
.isNull();
softly.assertThat(stcErrorTimer)
.as("subscribe to error timer is lazily registered")
.isNull();
softly.assertThat(stcCancelTimer.max(TimeUnit.MILLISECONDS))
.as("subscribe to cancel timer")
.isGreaterThanOrEqualTo(100);
});
}
@Override
public Mono<Payload> requestResponse(Payload payload) {
return Mono.defer(() -> {
Timer.Sample sample = requestResponse.start();
return delegate.requestResponse(payload)
.doFinally(signalType -> requestResponse.accept(sample, signalType));
});
}
Http2ServerConnectionHandler(Http2ConnectionDecoder decoder, Http2ConnectionEncoder encoder,
Http2Settings initialSettings, Channel channel, ServerConfig config,
Timer keepAliveTimer, GracefulShutdownSupport gracefulShutdownSupport,
String scheme) {
super(decoder, encoder, initialSettings);
this.gracefulShutdownSupport = gracefulShutdownSupport;
if (config.idleTimeoutMillis() > 0 || config.pingIntervalMillis() > 0) {
keepAliveHandler = new Http2ServerKeepAliveHandler(
channel, encoder().frameWriter(), keepAliveTimer,
config.idleTimeoutMillis(), config.pingIntervalMillis(), config.maxConnectionAgeMillis());
} else {
keepAliveHandler = null;
}
requestDecoder = new Http2RequestDecoder(config, channel, encoder(), scheme, keepAliveHandler);
connection().addListener(requestDecoder);
decoder().frameListener(requestDecoder);
// Setup post build options
final long timeout = config.idleTimeoutMillis();
if (timeout > 0) {
gracefulShutdownTimeoutMillis(timeout);
} else {
// Timeout disabled
gracefulShutdownTimeoutMillis(-1);
}
}
@Test
public void subscribeToError() {
Mono<Long> source = Mono.delay(Duration.ofMillis(100))
.map(v -> 100 / v)
.hide();
new MonoMetrics<>(source, registry)
.onErrorReturn(-1L)
.block();
Timer stcCompleteTimer = registry.find(METER_FLOW_DURATION)
.tags(Tags.of(TAG_ON_COMPLETE))
.timer();
Timer stcErrorTimer = registry.find(METER_FLOW_DURATION)
.tags(Tags.of(TAG_ON_ERROR))
.timer();
Timer stcCancelTimer = registry.find(METER_FLOW_DURATION)
.tags(Tags.of(TAG_CANCEL))
.timer();
SoftAssertions.assertSoftly(softly -> {
softly.assertThat(stcCompleteTimer)
.as("subscribe to complete timer")
.isNull();
softly.assertThat(stcErrorTimer.max(TimeUnit.MILLISECONDS))
.as("subscribe to error timer")
.isGreaterThanOrEqualTo(100);
assertThat(stcCancelTimer)
.as("subscribe to cancel timer")
.isNull();
});
}
@Test
@DirtiesContext
public void testAutoDiscovery() {
log.info("--- Starting tests with full auto discovery ---");
assertEquals(METHOD_COUNT * 2, this.meterRegistry.getMeters().stream()
.filter(Counter.class::isInstance)
.filter(m -> m.getId().getName().startsWith("grpc.")) // Only count grpc metrics
.count());
assertEquals(METHOD_COUNT, this.meterRegistry.getMeters().stream()
.filter(Timer.class::isInstance)
.filter(m -> m.getId().getName().startsWith("grpc.")) // Only count grpc metrics
.count());
log.info("--- Test completed ---");
}
protected Http2KeepAliveHandler(Channel channel, Http2FrameWriter frameWriter, String name,
Timer keepAliveTimer, long idleTimeoutMillis, long pingIntervalMillis,
long maxConnectionAgeMillis) {
super(channel, name, keepAliveTimer, idleTimeoutMillis, pingIntervalMillis, maxConnectionAgeMillis);
this.channel = requireNonNull(channel, "channel");
this.frameWriter = requireNonNull(frameWriter, "frameWriter");
}
@Test
void unwantedGaugesAreFilteredOut() {
final DropwizardMeterRegistry micrometer = DropwizardMeterRegistries.newRegistry();
final MetricRegistry dropwizard = micrometer.getDropwizardRegistry();
final DistributionSummary percentileSummary = DistributionSummary.builder("percentileSummary")
.publishPercentiles(0.5, 0.99)
.register(micrometer);
final DistributionSummary histogramSummary = DistributionSummary.builder("histogramSummary")
.sla(10, 100)
.register(micrometer);
final Timer percentileTimer = Timer.builder("percentileTimer")
.publishPercentiles(0.5, 0.99)
.register(micrometer);
final Timer histogramTimer = Timer.builder("histogramTimer")
.sla(Duration.ofSeconds(10), Duration.ofSeconds(100))
.register(micrometer);
percentileSummary.record(42);
histogramSummary.record(42);
percentileTimer.record(42, TimeUnit.SECONDS);
histogramTimer.record(42, TimeUnit.SECONDS);
final Map<String, Double> measurements = MoreMeters.measureAll(micrometer);
measurements.forEach((key, value) -> assertThat(key).doesNotContain(".percentile")
.doesNotContain(".histogram")
.doesNotContain("phi=")
.doesNotContain("le="));
// Must be exported as 2 Histograms and 2 Timers only.
assertThat(dropwizard.getHistograms()).hasSize(2);
assertThat(dropwizard.getTimers()).hasSize(2);
}
@Test
@DisplayName("total time and count are preserved for a single timing")
default void record(MeterRegistry registry) {
Timer t = registry.timer("myTimer");
t.record(42, TimeUnit.MILLISECONDS);
clock(registry).add(step());
assertAll(() -> assertEquals(1L, t.count()),
() -> assertEquals(42, t.totalTime(TimeUnit.MILLISECONDS), 1.0e-12));
}