blob: f06a961a125c7cec62c636b85ac62fa7cc8ebbfe [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
18import org.apache.felix.scr.annotations.Activate;
19import org.apache.felix.scr.annotations.Component;
20import org.apache.felix.scr.annotations.Deactivate;
21import org.apache.felix.scr.annotations.Reference;
22import org.apache.felix.scr.annotations.ReferenceCardinality;
23import org.apache.felix.scr.annotations.Service;
24import org.onosproject.openstacktelemetry.api.FlowInfo;
25import org.onosproject.openstacktelemetry.api.OpenstackTelemetryService;
26import org.onosproject.openstacktelemetry.api.PrometheusTelemetryAdminService;
27import org.onosproject.openstacktelemetry.api.config.PrometheusTelemetryConfig;
28import org.onosproject.openstacktelemetry.api.config.TelemetryConfig;
29import 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 */
42@Component(immediate = true)
43@Service
44public class PrometheusTelemetryManager implements PrometheusTelemetryAdminService {
45
46 private final Logger log = LoggerFactory.getLogger(getClass());
47
48 private Server prometheusExporter;
49
50 private static final String BYTE_VM2VM = "byte_vm2vm";
51 private static final String BYTE_DEVICE = "byte_device";
52 private static final String BYTE_SRC_IP = "byte_src_ip";
53 private static final String BYTE_DST_IP = "byte_dst_ip";
54
55 private static final String PKT_VM2VM = "pkt_vm2vm";
56 private static final String PKT_DEVICE = "pkt_device";
57 private static final String PKT_SRC_IP = "pkt_src_ip";
58 private static final String PKT_DST_IP = "pkt_dst_ip";
59
60 private static final String PKT_ERROR = "pkt_error";
61 private static final String PKT_DROP = "pkt_drop";
62
63 private static final String LABEL_IP_5_TUPLE = "IP_5_TUPLE";
64 private static final String LABEL_DEV_ID = "DEVICE_ID";
65 private static final String LABEL_SRC_IP = "SOURCE_IP";
66 private static final String LABEL_DST_IP = "DESTINATION_IP";
67
68 private static final String HELP_MSG = "SONA Flow statistics";
69
70 private static Counter byteVM2VM = Counter.build().name(BYTE_VM2VM)
71 .help(HELP_MSG)
72 .labelNames(LABEL_IP_5_TUPLE).register();
73
74 private static Counter byteDevice = Counter.build().name(BYTE_DEVICE)
75 .help(HELP_MSG)
76 .labelNames(LABEL_DEV_ID).register();
77
78 private static Counter byteSrcIp = Counter.build().name(BYTE_SRC_IP)
79 .help(HELP_MSG)
80 .labelNames(LABEL_SRC_IP).register();
81
82 private static Counter byteDstIp = Counter.build().name(BYTE_DST_IP)
83 .help(HELP_MSG)
84 .labelNames(LABEL_DST_IP).register();
85
86 private static Counter pktVM2VM = Counter.build().name(PKT_VM2VM)
87 .help(HELP_MSG)
88 .labelNames(LABEL_IP_5_TUPLE).register();
89
90 private static Counter pktDevice = Counter.build().name(PKT_DEVICE)
91 .help(HELP_MSG)
92 .labelNames(LABEL_DEV_ID).register();
93
94 private static Counter pktSrcIp = Counter.build().name(PKT_SRC_IP)
95 .help(HELP_MSG)
96 .labelNames(LABEL_SRC_IP).register();
97
98 private static Counter pktDstIp = Counter.build().name(PKT_DST_IP)
99 .help(HELP_MSG)
100 .labelNames(LABEL_DST_IP).register();
101
102 private static Counter pktError = Counter.build().name(PKT_ERROR)
103 .help(HELP_MSG)
104 .register();
105 private static Counter pktDrop = Counter.build().name(PKT_DROP)
106 .help(HELP_MSG)
107 .register();
108
109 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
110 protected OpenstackTelemetryService openstackTelemetryService;
111
112 @Activate
113 protected void activate() {
114 openstackTelemetryService.addTelemetryService(this);
115 log.info("Started");
116 }
117
118 @Deactivate
119 protected void deactivate() {
120 stop();
121 openstackTelemetryService.removeTelemetryService(this);
122 log.info("Stopped");
123 }
124
125 @Override
126 public void start(TelemetryConfig config) {
127 log.info("Prometheus exporter starts.");
128
129 PrometheusTelemetryConfig prometheusConfig = (PrometheusTelemetryConfig) config;
130
131 try {
132 // TODO Offer a 'Authentication'
133 prometheusExporter = new Server(prometheusConfig.port());
134 ServletContextHandler context = new ServletContextHandler();
135 context.setContextPath("/");
136 prometheusExporter.setHandler(context);
137 context.addServlet(new ServletHolder(new MetricsServlet()), "/metrics");
138
139 log.info("Prometeus server start");
140
141 prometheusExporter.start();
142 } catch (Exception ex) {
143 log.warn("Exception: {}", ex.toString());
144 }
145 }
146
147 @Override
148 public void stop() {
149 try {
150 prometheusExporter.stop();
151 } catch (Exception ex) {
152 log.warn("Exception: {}", ex.toString());
153 }
154 log.info("Prometheus exporter has stopped");
155 }
156
157 @Override
158 public void restart(TelemetryConfig config) {
159 stop();
160 start(config);
161 }
162
163 @Override
164 public void publish(Set<FlowInfo> flowInfos) {
165 if (flowInfos.size() == 0) {
166 log.debug("No record to publish");
167 return;
168 }
169
170 long flowByte;
171 int flowPkt;
172 for (FlowInfo flowInfo: flowInfos) {
173 flowByte = flowInfo.statsInfo().currAccBytes() - flowInfo.statsInfo().prevAccBytes();
174 flowPkt = flowInfo.statsInfo().currAccPkts() - flowInfo.statsInfo().prevAccPkts();
175
176 byteVM2VM.labels(flowInfo.uniqueFlowInfoKey()).inc(flowByte);
177 byteDevice.labels(flowInfo.deviceId().toString()).inc(flowByte);
178 byteSrcIp.labels(flowInfo.srcIp().toString()).inc(flowByte);
179 byteDstIp.labels(flowInfo.dstIp().toString()).inc(flowByte);
180
181 pktVM2VM.labels(flowInfo.uniqueFlowInfoKey()).inc(flowPkt);
182 pktDevice.labels(flowInfo.deviceId().toString()).inc(flowPkt);
183 pktSrcIp.labels(flowInfo.srcIp().toString()).inc(flowPkt);
184 pktDstIp.labels(flowInfo.dstIp().toString()).inc(flowPkt);
185
186 pktError.inc(flowInfo.statsInfo().errorPkts());
187 pktDrop.inc(flowInfo.statsInfo().dropPkts());
188 }
189 }
190
191 @Override
192 public boolean isRunning() {
193 log.info("Prometheus Exporter State: {}", prometheusExporter.isRunning());
194 return prometheusExporter.isRunning();
195 }
196}