e963bc6d2112616e256e872493ebb63caa8226db
[vpp.git] / vpp / vpp-api / vpp_get_metrics.c
1 /* 
2  * Copyright (c) 2016 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <sys/types.h>
19 #include <sys/mman.h>
20 #include <sys/stat.h>
21 #include <netinet/in.h>
22 #include <signal.h>
23 #include <pthread.h>
24 #include <unistd.h>
25 #include <time.h>
26 #include <fcntl.h>
27 #include <string.h>
28 #include <vppinfra/clib.h>
29 #include <vppinfra/vec.h>
30 #include <vppinfra/hash.h>
31 #include <vppinfra/bitmap.h>
32 #include <vppinfra/fifo.h>
33 #include <vppinfra/time.h>
34 #include <vppinfra/mheap.h>
35 #include <vppinfra/heap.h>
36 #include <vppinfra/pool.h>
37 #include <vppinfra/format.h>
38 #include <vlibapi/api.h>
39 #include <vlibmemory/api.h>
40
41 #include <vlib/vlib.h>
42 #include <vlib/unix/unix.h>
43 #include <vnet/api_errno.h>
44
45 #include <svmdb.h>
46
47 svmdb_client_t *c;
48 volatile int signal_received;
49
50 static void
51 unix_signal_handler (int signum, siginfo_t * si, ucontext_t * uc)
52 {
53   static int once;
54
55   if (once)
56     exit (1);
57
58   once = 1;
59   signal_received = 1;
60 }
61
62 static void
63 setup_signal_handlers (void)
64 {
65   uword i;
66   struct sigaction sa;
67
68   for (i = 1; i < 32; i++)
69     {
70       memset (&sa, 0, sizeof (sa));
71       sa.sa_sigaction = (void *) unix_signal_handler;
72       sa.sa_flags = SA_SIGINFO;
73
74       switch (i)
75         {
76           /* these signals take the default action */
77         case SIGABRT:
78         case SIGKILL:
79         case SIGSTOP:
80         case SIGUSR1:
81         case SIGUSR2:
82           continue;
83
84           /* ignore SIGPIPE, SIGCHLD */
85         case SIGPIPE:
86         case SIGCHLD:
87           sa.sa_sigaction = (void *) SIG_IGN;
88           break;
89
90           /* catch and handle all other signals */
91         default:
92           break;
93         }
94
95       if (sigaction (i, &sa, 0) < 0)
96         return clib_unix_warning (0, "sigaction %U", format_signal, i);
97     }
98 }
99
100 int
101 main (int argc, char **argv)
102 {
103   unformat_input_t input;
104   char *chroot_path = 0;
105   u8 *chroot_path_u8;
106   int interval = 0;
107   f64 *vector_ratep, *rx_ratep, *sig_error_ratep;
108   pid_t *vpp_pidp;
109
110   unformat_init_command_line (&input, argv);
111
112   while (unformat_check_input (&input) != UNFORMAT_END_OF_INPUT)
113     {
114       if (unformat (&input, "chroot %s", &chroot_path_u8))
115         {
116           chroot_path = (char *) chroot_path_u8;
117         }
118       else if (unformat (&input, "interval %d", &interval))
119         ;
120       else
121         {
122           fformat (stderr,
123                    "usage: vpp_get_metrics [chroot <path>] [interval <nn>]\n");
124           exit (1);
125         }
126     }
127
128   setup_signal_handlers ();
129
130   c = svmdb_map_chroot (chroot_path);
131
132   vpp_pidp =
133     svmdb_local_get_variable_reference (c, SVMDB_NAMESPACE_VEC, "vpp_pid");
134   vector_ratep =
135     svmdb_local_get_variable_reference (c, SVMDB_NAMESPACE_VEC,
136                                         "vpp_vector_rate");
137   rx_ratep =
138     svmdb_local_get_variable_reference (c, SVMDB_NAMESPACE_VEC,
139                                         "vpp_input_rate");
140   sig_error_ratep =
141     svmdb_local_get_variable_reference (c, SVMDB_NAMESPACE_VEC,
142                                         "vpp_sig_error_rate");
143
144   /* 
145    * Make sure vpp is actually running. Otherwise, there's every
146    * chance that the database region will be wiped out by the
147    * process monitor script
148    */
149
150   if (vpp_pidp == 0 || vector_ratep == 0 || rx_ratep == 0
151       || sig_error_ratep == 0)
152     {
153       fformat (stdout, "vpp not running\n");
154       exit (1);
155     }
156
157   do
158     {
159       /* Once vpp exits, the svm db region will be recreated... */
160       if (*vpp_pidp == 0 || kill (*vpp_pidp, 0) < 0)
161         {
162           fformat (stdout, "vpp not running\n");
163           exit (1);
164         }
165       fformat (stdout,
166                "%d: vpp_vector_rate=%.2f, vpp_input_rate=%f, vpp_sig_error_rate=%f\n",
167                *vpp_pidp, *vector_ratep, *rx_ratep, *sig_error_ratep);
168
169       if (interval)
170         sleep (interval);
171       if (signal_received)
172         break;
173     }
174   while (interval);
175
176   svmdb_unmap (c);
177   exit (0);
178 }
179
180 /*
181  * fd.io coding-style-patch-verification: ON
182  *
183  * Local Variables:
184  * eval: (c-set-style "gnu")
185  * End:
186  */