Fix path to VES library in vFW script
[demo.git] / vnfs / VESreporting_vFW5.0 / vpp_measurement_reporter.c
1
2 /*************************************************************************//**
3  *
4  * Copyright © 2019 AT&T Intellectual Property. All rights reserved.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *        http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and 
15  * limitations under the License.
16  *
17  ****************************************************************************/
18
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <unistd.h>
22 #include <string.h>
23 #include <sys/time.h>
24
25 #include "evel.h"
26
27 #define BUFSIZE 128
28 #define READ_INTERVAL 10
29
30 typedef struct dummy_vpp_metrics_struct {
31   int bytes_in;
32   int bytes_out;
33   int packets_in;
34   int packets_out;
35 } vpp_metrics_struct;
36
37 void read_vpp_metrics(vpp_metrics_struct *, char *);
38
39 int main(int argc, char** argv)
40 {
41   EVEL_ERR_CODES evel_rc = EVEL_SUCCESS;
42   EVENT_MEASUREMENT* vpp_m = NULL;
43   EVENT_HEADER* vpp_m_header = NULL;
44   EVENT_HEADER* batch_header = NULL;
45   MEASUREMENT_VNIC_PERFORMANCE * vnic_performance = NULL;
46   int bytes_in_this_round;
47   int bytes_out_this_round;
48   int packets_in_this_round;
49   int packets_out_this_round;
50   vpp_metrics_struct* last_vpp_metrics = malloc(sizeof(vpp_metrics_struct));
51   vpp_metrics_struct* curr_vpp_metrics = malloc(sizeof(vpp_metrics_struct));
52   struct timeval time_val;
53   time_t start_epoch;
54   time_t last_epoch;
55   char hostname[BUFSIZE];
56   char eventName[BUFSIZE];
57   char eventId[BUFSIZE];
58   char* fqdn2 = NULL;
59   int port2 = 0;
60   char * vnic = NULL;
61   memset(eventName, 0, BUFSIZE);
62   memset(eventId, 0, BUFSIZE);
63   memset(hostname, 0, BUFSIZE);
64
65   strcpy(eventName, "measurement_vFirewall-Att-Linkdownerr");
66   strcpy(eventId, "mvfs00000001");
67
68   char* fqdn = argv[1];
69   int port = atoi(argv[2]);
70   if(argc == 6)
71   {
72      fqdn2 = argv[3];
73      port2 = atoi(argv[4]);
74      vnic = argv[5];
75   }
76   else
77      vnic = argv[3];
78
79   printf("\nVector Packet Processing (VPP) measurement collection\n");
80   fflush(stdout);
81
82   if (!((argc == 4) || (argc == 6)))
83   {
84     fprintf(stderr, "Usage: %s <FQDN>|<IP address> <port> <FQDN>|<IP address> <port> <interface> \n", argv[0]);
85     fprintf(stderr, "OR\n");
86     fprintf(stderr, "Usage: %s <FQDN>|<IP address> <port> <interface>\n", argv[0]);
87     exit(-1);
88   }
89
90   /**************************************************************************/
91   /* Initialize                                                             */
92   /**************************************************************************/
93   if(evel_initialize(fqdn,                         /* FQDN                  */
94                      port,                         /* Port                  */
95                      fqdn2,                        /* Backup FQDN           */
96                      port2,                        /* Backup port           */
97                      NULL,                         /* optional path         */
98                      NULL,                         /* optional topic        */
99                      100,                          /* Ring Buffer size      */
100                      0,                            /* HTTPS?                */
101                      NULL,                         /* cert file             */
102                      NULL,                         /* key  file             */
103                      NULL,                         /* ca   info             */
104                      NULL,                         /* ca   file             */
105                      0,                            /* verify peer           */
106                      0,                            /* verify host           */
107                      "sample1",                    /* Username              */
108                      "sample1",                    /* Password              */
109                      "sample1",                    /* Username2             */
110                      "sample1",                    /* Password2             */
111                      NULL,                         /* Source ip             */
112                      NULL,                         /* Source ip2            */
113                      EVEL_SOURCE_VIRTUAL_MACHINE,  /* Source type           */
114                      "vFirewall",                  /* Role                  */
115                      1))                           /* Verbosity             */
116
117   {
118     fprintf(stderr, "\nFailed to initialize the EVEL library!!!\n");
119     exit(-1);
120   }
121   else
122   {
123     printf("\nInitialization completed\n");
124   }
125
126   gethostname(hostname, BUFSIZE);
127   memset(last_vpp_metrics, 0, sizeof(vpp_metrics_struct));
128   read_vpp_metrics(last_vpp_metrics, vnic);
129   gettimeofday(&time_val, NULL);
130   start_epoch = time_val.tv_sec * 1000000 + time_val.tv_usec;
131   sleep(READ_INTERVAL);
132
133   /***************************************************************************/
134   /* Collect metrics from the VNIC                                           */
135   /***************************************************************************/
136   while(1) {
137     memset(curr_vpp_metrics, 0, sizeof(vpp_metrics_struct));
138     read_vpp_metrics(curr_vpp_metrics, vnic);
139
140     if(curr_vpp_metrics->bytes_in - last_vpp_metrics->bytes_in > 0) {
141       bytes_in_this_round = curr_vpp_metrics->bytes_in - last_vpp_metrics->bytes_in;
142     }
143     else {
144       bytes_in_this_round = 0;
145     }
146     if(curr_vpp_metrics->bytes_out - last_vpp_metrics->bytes_out > 0) {
147       bytes_out_this_round = curr_vpp_metrics->bytes_out - last_vpp_metrics->bytes_out;
148     }
149     else {
150       bytes_out_this_round = 0;
151     }
152     if(curr_vpp_metrics->packets_in - last_vpp_metrics->packets_in > 0) {
153       packets_in_this_round = curr_vpp_metrics->packets_in - last_vpp_metrics->packets_in;
154     }
155     else {
156       packets_in_this_round = 0;
157     }
158     if(curr_vpp_metrics->packets_out - last_vpp_metrics->packets_out > 0) {
159       packets_out_this_round = curr_vpp_metrics->packets_out - last_vpp_metrics->packets_out;
160     }
161     else {
162       packets_out_this_round = 0;
163     }
164
165     vpp_m = evel_new_measurement(READ_INTERVAL, eventName, eventId);
166
167     if(vpp_m != NULL) {
168       printf("New measurement report created...\n");
169       vnic_performance = (MEASUREMENT_VNIC_PERFORMANCE *)evel_measurement_new_vnic_performance(vnic, "true");
170       evel_meas_vnic_performance_add(vpp_m, vnic_performance);
171       evel_vnic_performance_rx_total_pkt_delta_set(vnic_performance, packets_in_this_round);
172       evel_vnic_performance_tx_total_pkt_delta_set(vnic_performance, packets_out_this_round);
173
174       evel_vnic_performance_rx_octets_delta_set(vnic_performance, bytes_in_this_round);
175       evel_vnic_performance_tx_octets_delta_set(vnic_performance, bytes_out_this_round);
176
177       /***************************************************************************/
178       /* Set parameters in the MEASUREMENT header packet                         */
179       /***************************************************************************/
180       last_epoch = start_epoch + READ_INTERVAL * 1000000;
181       vpp_m_header = (EVENT_HEADER *)vpp_m;
182       vpp_m_header->start_epoch_microsec = start_epoch;
183       vpp_m_header->last_epoch_microsec = last_epoch;
184       evel_reporting_entity_id_set(vpp_m_header, "No UUID available");
185 printf("1111\n");
186       evel_reporting_entity_name_set(vpp_m_header, hostname);
187 printf("1111\n");
188      // evel_rc = evel_post_event(vpp_m_header);
189       batch_header = evel_new_batch("batch_event_name", "bevent_id");
190       evel_batch_add_event(batch_header, vpp_m_header);
191       evel_rc = evel_post_event(batch_header);
192
193       if(evel_rc == EVEL_SUCCESS) {
194         printf("Measurement report correctly sent to the collector!\n");
195       }
196       else {
197         printf("Post failed %d (%s)\n", evel_rc, evel_error_string());
198       }
199     }
200     else {
201       printf("New measurement report failed (%s)\n", evel_error_string());
202     }
203
204     last_vpp_metrics->bytes_in = curr_vpp_metrics->bytes_in;
205     last_vpp_metrics->bytes_out = curr_vpp_metrics->bytes_out;
206     last_vpp_metrics->packets_in = curr_vpp_metrics->packets_in;
207     last_vpp_metrics->packets_out = curr_vpp_metrics->packets_out;
208     gettimeofday(&time_val, NULL);
209     start_epoch = time_val.tv_sec * 1000000 + time_val.tv_usec;
210
211     sleep(READ_INTERVAL);
212   }
213
214   /***************************************************************************/
215   /* Terminate                                                               */
216   /***************************************************************************/
217   sleep(1);
218   free(last_vpp_metrics);
219   free(curr_vpp_metrics);
220   evel_terminate();
221   printf("Terminated\n");
222
223   return 0;
224 }
225
226 void read_vpp_metrics(vpp_metrics_struct *vpp_metrics, char *vnic) {
227   // Define an array of char that contains the parameters of the unix 'cut' command
228   char* params[] = {"-f3", "-f11", "-f4", "-f12"};
229   // Define the unix command to execute in order to read metrics from the vNIC
230   char* cmd_prefix = "sudo cat /proc/net/dev | grep \"";
231   char* cmd_mid = "\" | tr -s \' \' | cut -d\' \' ";
232   char cmd[BUFSIZE];
233   // Define other variables
234   char buf[BUFSIZE];            /* buffer used to store VPP metrics     */
235   int temp[] = {0, 0, 0, 0};    /* temp array that contains VPP values  */
236   FILE *fp;                     /* file descriptor to pipe cmd to shell */
237   int i;
238
239   for(i = 0; i < 4; i++) {
240     // Clear buffers
241     memset(buf, 0, BUFSIZE);
242     memset(cmd, 0, BUFSIZE);
243     // Build shell command to read metrics from the vNIC
244     strcat(cmd, cmd_prefix);
245     strcat(cmd, vnic);
246     strcat(cmd, cmd_mid);
247     strcat(cmd, params[i]);
248     
249     // Open a pipe and read VPP values
250     if ((fp = popen(cmd, "r")) == NULL) {
251         printf("Error opening pipe!\n");
252         return;
253     }
254
255     while (fgets(buf, BUFSIZE, fp) != NULL);
256     temp[i] = atoi(buf);
257
258     if(pclose(fp))  {
259         printf("Command not found or exited with error status\n");
260         return;
261     }
262   }
263
264   // Store metrics read from the vNIC in the struct passed from the main function
265   vpp_metrics->bytes_in = temp[0];
266   vpp_metrics->bytes_out = temp[1];
267   vpp_metrics->packets_in = temp[2];
268   vpp_metrics->packets_out = temp[3];
269 }