Skip to content

Commit 80dcd09

Browse files
committed
Micrometer module, fix jooby-project#1115
1 parent 1fc96c4 commit 80dcd09

File tree

14 files changed

+2615
-6
lines changed

14 files changed

+2615
-6
lines changed

doc/doc/micrometer/micrometer.md

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
# micrometer
2+
3+
<a href="https://micrometer.io/">Micrometer</a> provides a simple facade over the instrumentation clients for the most popular monitoring systems, allowing you to instrument your JVM-based application code without vendor lock-in. Think SLF4J, but for metrics.
4+
5+
## dependency
6+
7+
```xml
8+
<dependency>
9+
<groupId>org.jooby</groupId>
10+
<artifactId>jooby-micrometer</artifactId>
11+
<version>{{version}}</version>
12+
</dependency>
13+
```
14+
15+
## exposes
16+
17+
* One or more ```MeterRegistry```
18+
19+
## usage
20+
21+
```java
22+
{
23+
use(new Micrometer());
24+
25+
// Timer example:
26+
use("*", (req, rsp, chain) -> {
27+
MeterRegistry registry = require(MeterRegistry.class);
28+
Timer timer = registry.timer("http.server.requests");
29+
timer.record(() -> chain.next(req, rsp));
30+
});
31+
}
32+
```
33+
34+
## monitoring systems
35+
36+
It is possible to attach one or more monitoring system. Here are some examples:
37+
38+
```java
39+
{
40+
use(new Micrometer()
41+
.atlas(conf -> {
42+
return new AtlasMeterRegistry(conf);
43+
})
44+
.prometheus(PrometheusMeterRegistry::new)
45+
// etc...
46+
);
47+
48+
}
49+
```
50+
51+
Jooby creates a ```MeterRegistryConfig``` for every available monitoring system. You control configuration properties via ```.conf``` file:
52+
53+
application.conf:
54+
55+
```
56+
micrometer {
57+
atlas {
58+
uri: "http://localhost:7101/api/v1/publish"
59+
}
60+
prometheus {
61+
step: "PT1M"
62+
}
63+
}
64+
65+
```
66+
67+
<a href="https://prometheus.io/">Prometheus</a> expects to scrape or poll individual app instances for metrics. Jooby provides a ready to use prometheus handler:
68+
69+
```java
70+
import org.jooby.micrometer.PrometheusHandler;
71+
{
72+
use(new Micrometer()
73+
.prometheus(PrometheusMeterRegistry::new)
74+
);
75+
76+
get("/metrics", new PrometheusHandler());
77+
78+
}
79+
```
80+
81+
## timed annotation
82+
83+
Jooby supports the ```io.micrometer.core.annotation.Timed``` annotation for MVC routes:
84+
85+
```java
86+
@Path("/controller")
87+
class Controller {
88+
89+
@Timed("people.all")
90+
public People list() {
91+
...
92+
}
93+
94+
}
95+
```
96+
97+
App:
98+
99+
```java
100+
import org.jooby.micrometer.TimedHandler;
101+
{
102+
use(new Micrometer());
103+
104+
use("*", new TimedHandler());
105+
}
106+
```
107+
108+
The ```TimedHandler``` record all the controller methods with ```io.micrometer.core.annotation.Timed``` annotation.
109+
110+
## advanced options
111+
112+
Advanced options are available via ```doWith``` method:
113+
114+
```java
115+
{
116+
use(new Micrometer()
117+
.doWith(registry -> {
118+
//work with registry
119+
})
120+
);
121+
122+
}
123+
```
124+
125+
That's all! Happy coding!!

jooby/src/main/java/org/jooby/Jooby.java

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2927,6 +2927,7 @@ private Injector bootstrap(final Config args,
29272927
Set<Object> routeClasses = new HashSet<>();
29282928
for (Object it : bag) {
29292929
Try.run(() -> bindService(
2930+
logger(this),
29302931
this.bag,
29312932
finalConfig,
29322933
finalEnv,
@@ -3074,7 +3075,8 @@ private static Provider<Session.Definition> session(final Config $session,
30743075
};
30753076
}
30763077

3077-
private static Throwing.Consumer<? super Object> bindService(final Set<Object> src,
3078+
private static Throwing.Consumer<? super Object> bindService(Logger log,
3079+
final Set<Object> src,
30783080
final Config conf,
30793081
final Env env,
30803082
final RouteMetadata rm,
@@ -3089,14 +3091,14 @@ private static Throwing.Consumer<? super Object> bindService(final Set<Object> s
30893091
return it -> {
30903092
if (it instanceof Jooby.Module) {
30913093
int from = src.size();
3092-
install((Jooby.Module) it, env, conf, binder);
3094+
install(log, (Jooby.Module) it, env, conf, binder);
30933095
int to = src.size();
30943096
// collect any route a module might add
30953097
if (to > from) {
30963098
List<Object> elements = normalize(new ArrayList<>(src).subList(from, to), env, rm,
30973099
caseSensitiveRouting);
30983100
for (Object e : elements) {
3099-
bindService(src,
3101+
bindService(log, src,
31003102
conf,
31013103
env,
31023104
rm,
@@ -3420,16 +3422,23 @@ private Config defaultConfig(final Config conf, final String cpath) {
34203422
/**
34213423
* Install a {@link Jooby.Module}.
34223424
*
3425+
* @param log Logger.
34233426
* @param module The module to install.
34243427
* @param env Application env.
34253428
* @param config The configuration object.
34263429
* @param binder A Guice binder.
34273430
* @throws Throwable If module bootstrap fails.
34283431
*/
3429-
private static void install(final Jooby.Module module, final Env env, final Config config,
3432+
private static void install(final Logger log, final Jooby.Module module, final Env env, final Config config,
34303433
final Binder binder) throws Throwable {
34313434
module.configure(env, config, binder);
3432-
binder.install(ProviderMethodsModule.forObject(module));
3435+
try {
3436+
binder.install(ProviderMethodsModule.forObject(module));
3437+
} catch (NoClassDefFoundError x) {
3438+
// Allow dynamic linking of optional dependencies (required by micrometer module), we ignore
3439+
// missing classes here, if there is a missing class Jooby is going to fails early (not here)
3440+
log.debug("ignoring class not found from guice provider method", x);
3441+
}
34333442
}
34343443

34353444
/**

modules/coverage-report/pom.xml

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@
9191
<source>${project.parent.basedir}/jooby-rocker/src/main/java</source>
9292
<source>${project.parent.basedir}/jooby-neo4j/src/main/java</source>
9393
<source>${project.parent.basedir}/jooby-jdbi3/src/main/java</source>
94+
<source>${project.parent.basedir}/jooby-micrometer/src/main/java</source>
9495
</sources>
9596
</configuration>
9697
</execution>
@@ -157,6 +158,7 @@
157158
<source>${project.parent.basedir}/jooby-rocker/src/test/java</source>
158159
<source>${project.parent.basedir}/jooby-neo4j/src/test/java</source>
159160
<source>${project.parent.basedir}/jooby-jdbi3/src/test/java</source>
161+
<source>${project.parent.basedir}/jooby-micrometer/src/test/java</source>
160162
</sources>
161163
</configuration>
162164
</execution>
@@ -964,6 +966,12 @@
964966
<version>${project.version}</version>
965967
</dependency>
966968

969+
<dependency>
970+
<groupId>org.jooby</groupId>
971+
<artifactId>jooby-micrometer</artifactId>
972+
<version>${project.version}</version>
973+
</dependency>
974+
967975
<dependency>
968976
<groupId>org.jooby</groupId>
969977
<artifactId>jooby-requery</artifactId>
@@ -1103,6 +1111,72 @@
11031111
</dependency>
11041112

11051113
<!-- Test dependencies -->
1114+
<dependency>
1115+
<groupId>io.micrometer</groupId>
1116+
<artifactId>micrometer-registry-prometheus</artifactId>
1117+
<optional>true</optional>
1118+
</dependency>
1119+
1120+
<dependency>
1121+
<groupId>io.micrometer</groupId>
1122+
<artifactId>micrometer-registry-atlas</artifactId>
1123+
<optional>true</optional>
1124+
</dependency>
1125+
1126+
<dependency>
1127+
<groupId>io.micrometer</groupId>
1128+
<artifactId>micrometer-registry-datadog</artifactId>
1129+
<optional>true</optional>
1130+
</dependency>
1131+
1132+
<dependency>
1133+
<groupId>io.micrometer</groupId>
1134+
<artifactId>micrometer-registry-ganglia</artifactId>
1135+
<optional>true</optional>
1136+
</dependency>
1137+
1138+
<dependency>
1139+
<groupId>io.micrometer</groupId>
1140+
<artifactId>micrometer-registry-graphite</artifactId>
1141+
<optional>true</optional>
1142+
</dependency>
1143+
1144+
<dependency>
1145+
<groupId>io.micrometer</groupId>
1146+
<artifactId>micrometer-registry-influx</artifactId>
1147+
<optional>true</optional>
1148+
</dependency>
1149+
1150+
<dependency>
1151+
<groupId>io.micrometer</groupId>
1152+
<artifactId>micrometer-registry-jmx</artifactId>
1153+
<optional>true</optional>
1154+
</dependency>
1155+
1156+
<dependency>
1157+
<groupId>io.micrometer</groupId>
1158+
<artifactId>micrometer-registry-new-relic</artifactId>
1159+
<optional>true</optional>
1160+
</dependency>
1161+
1162+
<dependency>
1163+
<groupId>io.micrometer</groupId>
1164+
<artifactId>micrometer-registry-signalfx</artifactId>
1165+
<optional>true</optional>
1166+
</dependency>
1167+
1168+
<dependency>
1169+
<groupId>io.micrometer</groupId>
1170+
<artifactId>micrometer-registry-statsd</artifactId>
1171+
<optional>true</optional>
1172+
</dependency>
1173+
1174+
<dependency>
1175+
<groupId>io.micrometer</groupId>
1176+
<artifactId>micrometer-registry-wavefront</artifactId>
1177+
<optional>true</optional>
1178+
</dependency>
1179+
11061180
<dependency>
11071181
<groupId>org.pac4j</groupId>
11081182
<artifactId>pac4j-cas</artifactId>

0 commit comments

Comments
 (0)