6
6
import io .fabric8 .kubernetes .client .KubernetesClient ;
7
7
import io .fabric8 .kubernetes .client .Watch ;
8
8
import io .fabric8 .kubernetes .client .utils .HttpClientUtils ;
9
+ import io .prometheus .client .Gauge ;
9
10
import io .prometheus .client .exporter .HTTPServer ;
10
11
import io .prometheus .client .hotspot .DefaultExports ;
12
+ import io .prometheus .client .log4j .InstrumentedAppender ;
11
13
import io .radanalytics .operator .common .AbstractOperator ;
12
14
import io .radanalytics .operator .common .AnsiColors ;
13
15
import io .radanalytics .operator .common .OperatorConfig ;
@@ -45,23 +47,25 @@ public class Entrypoint {
45
47
46
48
public static ExecutorService EXECUTORS = Executors .newFixedThreadPool (10 );
47
49
50
+ private static OperatorConfig config ;
51
+ private static KubernetesClient client ;
52
+
48
53
public static void main (String [] args ) {
49
54
log .info ("Starting.." );
50
- OperatorConfig config = OperatorConfig .fromMap (System .getenv ());
51
- KubernetesClient client = new DefaultKubernetesClient ();
52
- boolean isOpenshift = isOnOpenShift (client );
53
- CompletableFuture <Void > future = run (client , isOpenshift , config ).exceptionally (ex -> {
55
+ config = OperatorConfig .fromMap (System .getenv ());
56
+ client = new DefaultKubernetesClient ();
57
+ boolean isOpenshift = isOnOpenShift ();
58
+ CompletableFuture <Void > future = run (isOpenshift ).exceptionally (ex -> {
54
59
log .error ("Unable to start operator for one or more namespaces" , ex );
55
60
System .exit (1 );
56
61
return null ;
57
62
});
58
63
if (config .isMetrics ()) {
59
- CompletableFuture <Optional <HTTPServer >> maybeMetricServer = future .thenCompose (s -> runMetrics (isOpenshift , config ));
60
- // todo: shutdown hook and top it if necessary
64
+ CompletableFuture <Optional <HTTPServer >> maybeMetricServer = future .thenCompose (s -> runMetrics (isOpenshift ));
61
65
}
62
66
}
63
67
64
- private static CompletableFuture <Void > run (KubernetesClient client , boolean isOpenShift , OperatorConfig config ) {
68
+ private static CompletableFuture <Void > run (boolean isOpenShift ) {
65
69
printInfo ();
66
70
67
71
if (isOpenShift ) {
@@ -73,20 +77,20 @@ private static CompletableFuture<Void> run(KubernetesClient client, boolean isOp
73
77
List <CompletableFuture > futures = new ArrayList <>();
74
78
if (null == config .getNamespaces ()) { // get the current namespace
75
79
String namespace = client .getNamespace ();
76
- CompletableFuture future = runForNamespace (client , isOpenShift , namespace , config .getReconciliationIntervalS (), 0 );
80
+ CompletableFuture future = runForNamespace (isOpenShift , namespace , config .getReconciliationIntervalS (), 0 );
77
81
futures .add (future );
78
82
} else {
79
83
Iterator <String > ns ;
80
84
int i ;
81
85
for (ns = config .getNamespaces ().iterator (), i = 0 ; i < config .getNamespaces ().size (); i ++) {
82
- CompletableFuture future = runForNamespace (client , isOpenShift , ns .next (), config .getReconciliationIntervalS (), i );
86
+ CompletableFuture future = runForNamespace (isOpenShift , ns .next (), config .getReconciliationIntervalS (), i );
83
87
futures .add (future );
84
88
}
85
89
}
86
90
return CompletableFuture .allOf (futures .toArray (new CompletableFuture []{}));
87
91
}
88
92
89
- private static CompletableFuture <Optional <HTTPServer >> runMetrics (boolean isOpenShift , OperatorConfig config ) {
93
+ private static CompletableFuture <Optional <HTTPServer >> runMetrics (boolean isOpenShift ) {
90
94
HTTPServer httpServer = null ;
91
95
try {
92
96
log .info ("Starting a simple HTTP server for exposing internal metrics.." );
@@ -104,7 +108,7 @@ private static CompletableFuture<Optional<HTTPServer>> runMetrics(boolean isOpen
104
108
return CompletableFuture .supplyAsync (() -> maybeServer );
105
109
}
106
110
107
- private static CompletableFuture <Void > runForNamespace (KubernetesClient client , boolean isOpenShift , String namespace , long reconInterval , int delay ) {
111
+ private static CompletableFuture <Void > runForNamespace (boolean isOpenShift , String namespace , long reconInterval , int delay ) {
108
112
List <ClassLoader > classLoadersList = new LinkedList <>();
109
113
classLoadersList .add (ClasspathHelper .contextClassLoader ());
110
114
classLoadersList .add (ClasspathHelper .staticClassLoader ());
@@ -172,7 +176,7 @@ private static CompletableFuture<Void> runForNamespace(KubernetesClient client,
172
176
return CompletableFuture .allOf (futures .toArray (new CompletableFuture []{}));
173
177
}
174
178
175
- private static boolean isOnOpenShift (KubernetesClient client ) {
179
+ private static boolean isOnOpenShift () {
176
180
URL kubernetesApi = client .getMasterUrl ();
177
181
178
182
HttpUrl .Builder urlBuilder = new HttpUrl .Builder ();
@@ -217,11 +221,56 @@ private static void printInfo() {
217
221
} catch (Exception e ) {
218
222
// ignore, not critical
219
223
}
224
+
225
+ if (config .isMetrics ()) {
226
+ registerMetrics (gitSha , version );
227
+ }
228
+
220
229
log .info ("\n {}Operator{} has started in version {}{}{}. {}\n " , re (), xx (), gr (),
221
230
version , xx (), FOO );
222
231
if (!gitSha .isEmpty ()) {
223
232
log .info ("Git sha: {}{}{}" , ye (), gitSha , xx ());
224
233
}
225
234
log .info ("==================\n " );
226
235
}
236
+
237
+ private static void registerMetrics (String gitSha , String version ) {
238
+ List <String > labels = new ArrayList <>();
239
+ List <String > values = new ArrayList <>();
240
+
241
+ labels .addAll (Arrays .asList ("gitSha" , "version" ,
242
+ "CRD" ,
243
+ "COLORS" ,
244
+ OperatorConfig .WATCHED_NAMESPACE ,
245
+ OperatorConfig .METRICS ,
246
+ OperatorConfig .METRICS_JVM ,
247
+ OperatorConfig .METRICS_PORT ,
248
+ OperatorConfig .FULL_RECONCILIATION_INTERVAL_S ,
249
+ OperatorConfig .OPERATOR_OPERATION_TIMEOUT_MS
250
+ ));
251
+ values .addAll (Arrays .asList (gitSha , version ,
252
+ Optional .ofNullable (System .getenv ().get ("CRD" )).orElse ("false" ),
253
+ Optional .ofNullable (System .getenv ().get ("COLORS" )).orElse ("true" ),
254
+ null == config .getNamespaces () ? client .getNamespace () : config .getNamespaces ().toString (),
255
+ String .valueOf (config .isMetrics ()),
256
+ String .valueOf (config .isMetricsJvm ()),
257
+ String .valueOf (config .getMetricsPort ()),
258
+ String .valueOf (config .getReconciliationIntervalS ()),
259
+ String .valueOf (config .getOperationTimeoutMs ())
260
+ ));
261
+
262
+ Gauge .build ()
263
+ .name ("operator_info" )
264
+ .help ("Basic information about the abstract operator library." )
265
+ .labelNames (labels .toArray (new String []{}))
266
+ .register ()
267
+ .labels (values .toArray (new String []{}))
268
+ .set (1 );
269
+
270
+ // add log appender for metrics
271
+ final org .apache .log4j .Logger rootLogger = org .apache .log4j .Logger .getRootLogger ();
272
+ InstrumentedAppender metricsLogAppender = new InstrumentedAppender ();
273
+ metricsLogAppender .setName ("metrics" );
274
+ rootLogger .addAppender (metricsLogAppender );
275
+ }
227
276
}
0 commit comments