blob: f029fa4e5f9cd23eeb3c16f0de4692073b03c9c4 [file] [log] [blame]
boyoung21c5f5f42018-09-27 20:29:41 +09001/*
2 * Copyright 2018-present Open Networking Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.onosproject.openstacktelemetry.impl;
17
boyoung21c5f5f42018-09-27 20:29:41 +090018import org.onosproject.openstacktelemetry.api.FlowInfo;
19import org.onosproject.openstacktelemetry.api.OpenstackTelemetryService;
20import org.onosproject.openstacktelemetry.api.PrometheusTelemetryAdminService;
Ray Milkeydf521292018-10-04 15:13:33 -070021import org.onosproject.openstacktelemetry.api.PrometheusTelemetryService;
boyoung21c5f5f42018-09-27 20:29:41 +090022import org.onosproject.openstacktelemetry.api.config.PrometheusTelemetryConfig;
23import org.onosproject.openstacktelemetry.api.config.TelemetryConfig;
Ray Milkeydf521292018-10-04 15:13:33 -070024import org.osgi.service.component.annotations.Activate;
25import org.osgi.service.component.annotations.Component;
26import org.osgi.service.component.annotations.Deactivate;
27import org.osgi.service.component.annotations.Reference;
28import org.osgi.service.component.annotations.ReferenceCardinality;
boyoung21c5f5f42018-09-27 20:29:41 +090029import org.slf4j.Logger;
30import org.slf4j.LoggerFactory;
31
32import io.prometheus.client.Counter;
33import io.prometheus.client.exporter.MetricsServlet;
34import org.eclipse.jetty.server.Server;
35import org.eclipse.jetty.servlet.ServletContextHandler;
36import org.eclipse.jetty.servlet.ServletHolder;
37import java.util.Set;
38
39/**
40 * Prometheus telemetry manager.
41 */
Ray Milkeydf521292018-10-04 15:13:33 -070042@Component(immediate = true, service = PrometheusTelemetryService.class)
boyoung21c5f5f42018-09-27 20:29:41 +090043public class PrometheusTelemetryManager implements PrometheusTelemetryAdminService {
44
45 private final Logger log = LoggerFactory.getLogger(getClass());
46
47 private Server prometheusExporter;
48
49 private static final String BYTE_VM2VM = "byte_vm2vm";
50 private static final String BYTE_DEVICE = "byte_device";
51 private static final String BYTE_SRC_IP = "byte_src_ip";
52 private static final String BYTE_DST_IP = "byte_dst_ip";
53
54 private static final String PKT_VM2VM = "pkt_vm2vm";
55 private static final String PKT_DEVICE = "pkt_device";
56 private static final String PKT_SRC_IP = "pkt_src_ip";
57 private static final String PKT_DST_IP = "pkt_dst_ip";
58
59 private static final String PKT_ERROR = "pkt_error";
60 private static final String PKT_DROP = "pkt_drop";
61
62 private static final String LABEL_IP_5_TUPLE = "IP_5_TUPLE";
63 private static final String LABEL_DEV_ID = "DEVICE_ID";
64 private static final String LABEL_SRC_IP = "SOURCE_IP";
65 private static final String LABEL_DST_IP = "DESTINATION_IP";
66
67 private static final String HELP_MSG = "SONA Flow statistics";
68
69 private static Counter byteVM2VM = Counter.build().name(BYTE_VM2VM)
70 .help(HELP_MSG)
71 .labelNames(LABEL_IP_5_TUPLE).register();
72
73 private static Counter byteDevice = Counter.build().name(BYTE_DEVICE)
74 .help(HELP_MSG)
75 .labelNames(LABEL_DEV_ID).register();
76
77 private static Counter byteSrcIp = Counter.build().name(BYTE_SRC_IP)
78 .help(HELP_MSG)
79 .labelNames(LABEL_SRC_IP).register();
80
81 private static Counter byteDstIp = Counter.build().name(BYTE_DST_IP)
82 .help(HELP_MSG)
83 .labelNames(LABEL_DST_IP).register();
84
85 private static Counter pktVM2VM = Counter.build().name(PKT_VM2VM)
86 .help(HELP_MSG)
87 .labelNames(LABEL_IP_5_TUPLE).register();
88
89 private static Counter pktDevice = Counter.build().name(PKT_DEVICE)
90 .help(HELP_MSG)
91 .labelNames(LABEL_DEV_ID).register();
92
93 private static Counter pktSrcIp = Counter.build().name(PKT_SRC_IP)
94 .help(HELP_MSG)
95 .labelNames(LABEL_SRC_IP).register();
96
97 private static Counter pktDstIp = Counter.build().name(PKT_DST_IP)
98 .help(HELP_MSG)
99 .labelNames(LABEL_DST_IP).register();
100
101 private static Counter pktError = Counter.build().name(PKT_ERROR)
102 .help(HELP_MSG)
103 .register();
104 private static Counter pktDrop = Counter.build().name(PKT_DROP)
105 .help(HELP_MSG)
106 .register();
107
Ray Milkeydf521292018-10-04 15:13:33 -0700108 @Reference(cardinality = ReferenceCardinality.MANDATORY)
boyoung21c5f5f42018-09-27 20:29:41 +0900109 protected OpenstackTelemetryService openstackTelemetryService;
110
111 @Activate
112 protected void activate() {
113 openstackTelemetryService.addTelemetryService(this);
114 log.info("Started");
115 }
116
117 @Deactivate
118 protected void deactivate() {
119 stop();
120 openstackTelemetryService.removeTelemetryService(this);
121 log.info("Stopped");
122 }
123
124 @Override
125 public void start(TelemetryConfig config) {
126 log.info("Prometheus exporter starts.");
127
128 PrometheusTelemetryConfig prometheusConfig = (PrometheusTelemetryConfig) config;
129
130 try {
131 // TODO Offer a 'Authentication'
132 prometheusExporter = new Server(prometheusConfig.port());
133 ServletContextHandler context = new ServletContextHandler();
134 context.setContextPath("/");
135 prometheusExporter.setHandler(context);
136 context.addServlet(new ServletHolder(new MetricsServlet()), "/metrics");
137
138 log.info("Prometeus server start");
139
140 prometheusExporter.start();
141 } catch (Exception ex) {
142 log.warn("Exception: {}", ex.toString());
143 }
144 }
145
146 @Override
147 public void stop() {
148 try {
149 prometheusExporter.stop();
150 } catch (Exception ex) {
151 log.warn("Exception: {}", ex.toString());
152 }
153 log.info("Prometheus exporter has stopped");
154 }
155
156 @Override
157 public void restart(TelemetryConfig config) {
158 stop();
159 start(config);
160 }
161
162 @Override
163 public void publish(Set<FlowInfo> flowInfos) {
164 if (flowInfos.size() == 0) {
165 log.debug("No record to publish");
166 return;
167 }
168
169 long flowByte;
170 int flowPkt;
171 for (FlowInfo flowInfo: flowInfos) {
172 flowByte = flowInfo.statsInfo().currAccBytes() - flowInfo.statsInfo().prevAccBytes();
173 flowPkt = flowInfo.statsInfo().currAccPkts() - flowInfo.statsInfo().prevAccPkts();
174
175 byteVM2VM.labels(flowInfo.uniqueFlowInfoKey()).inc(flowByte);
176 byteDevice.labels(flowInfo.deviceId().toString()).inc(flowByte);
177 byteSrcIp.labels(flowInfo.srcIp().toString()).inc(flowByte);
178 byteDstIp.labels(flowInfo.dstIp().toString()).inc(flowByte);
179
180 pktVM2VM.labels(flowInfo.uniqueFlowInfoKey()).inc(flowPkt);
181 pktDevice.labels(flowInfo.deviceId().toString()).inc(flowPkt);
182 pktSrcIp.labels(flowInfo.srcIp().toString()).inc(flowPkt);
183 pktDstIp.labels(flowInfo.dstIp().toString()).inc(flowPkt);
184
185 pktError.inc(flowInfo.statsInfo().errorPkts());
186 pktDrop.inc(flowInfo.statsInfo().dropPkts());
187 }
188 }
189
190 @Override
191 public boolean isRunning() {
192 log.info("Prometheus Exporter State: {}", prometheusExporter.isRunning());
193 return prometheusExporter.isRunning();
194 }
195}