1 | /* |
2 | This file is part of Mtproto-proxy Library. |
3 | |
4 | Mtproto-proxy Library is free software: you can redistribute it and/or modify |
5 | it under the terms of the GNU Lesser General Public License as published by |
6 | the Free Software Foundation, either version 2 of the License, or |
7 | (at your option) any later version. |
8 | |
9 | Mtproto-proxy Library is distributed in the hope that it will be useful, |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 | GNU Lesser General Public License for more details. |
13 | |
14 | You should have received a copy of the GNU Lesser General Public License |
15 | along with Mtproto-proxy Library. If not, see <http://www.gnu.org/licenses/>. |
16 | |
17 | Copyright 2015-2016 Telegram Messenger Inc |
18 | 2015-2016 Vitaly Valtman |
19 | |
20 | */ |
21 | #define _FILE_OFFSET_BITS 64 |
22 | |
23 | #include <arpa/inet.h> |
24 | #include <assert.h> |
25 | #include <errno.h> |
26 | #include <fcntl.h> |
27 | #include <math.h> |
28 | #include <netinet/in.h> |
29 | #include <netinet/tcp.h> |
30 | #include <stddef.h> |
31 | #include <stdio.h> |
32 | #include <stdlib.h> |
33 | #include <string.h> |
34 | #include <sys/epoll.h> |
35 | #include <sys/socket.h> |
36 | #include <sys/uio.h> |
37 | #include <time.h> |
38 | #include <unistd.h> |
39 | |
40 | #include "crc32.h" |
41 | #include "net/net-events.h" |
42 | #include "kprintf.h" |
43 | #include "precise-time.h" |
44 | #include "server-functions.h" |
45 | #include "net/net-connections.h" |
46 | #include "net/net-config.h" |
47 | #include "vv/vv-io.h" |
48 | #include "pid.h" |
49 | #include "common/common-stats.h" |
50 | |
51 | #include "net/net-msg-buffers.h" |
52 | |
53 | #include "engine/engine.h" |
54 | |
55 | struct process_id PID; |
56 | |
57 | extern int zheap_debug; |
58 | long long queries_allocated; |
59 | long long max_queries_allocated; |
60 | long long max_queries_allocated_sec; |
61 | long long max_queries_allocated_prev_sec; |
62 | |
63 | long long total_vv_tree_nodes; |
64 | |
65 | int tl_rpc_op_stat __attribute__ ((weak)); |
66 | int op_stat_write (stats_buffer_t *sb) __attribute__ ((weak)); |
67 | int op_stat_write (stats_buffer_t *sb) { return 0; } |
68 | |
69 | |
70 | int my_pid; |
71 | |
72 | int connections_prepare_stat (stats_buffer_t *sb); |
73 | int udp_prepare_stat (stats_buffer_t *sb); |
74 | int tl_parse_prepare_stat (stats_buffer_t *sb); |
75 | int raw_msg_prepare_stat (stats_buffer_t *sb); |
76 | int raw_msg_buffer_prepare_stat (stats_buffer_t *sb); |
77 | int crypto_aes_prepare_stat (stats_buffer_t *sb); |
78 | int crypto_dh_prepare_stat (stats_buffer_t *sb); |
79 | int jobs_prepare_stat (stats_buffer_t *sb); |
80 | int aio_prepare_stat (stats_buffer_t *sb); |
81 | int mp_queue_prepare_stat (stats_buffer_t *sb); |
82 | int timers_prepare_stat (stats_buffer_t *sb); |
83 | int rpc_targets_prepare_stat (stats_buffer_t *sb); |
84 | |
85 | //static double safe_div (double x, double y) { return y > 0 ? x/y : 0; } |
86 | |
87 | int recent_idle_percent (void) { |
88 | return a_idle_quotient > 0 ? a_idle_time / a_idle_quotient * 100 : a_idle_time; |
89 | } |
90 | |
91 | extern long long epoll_calls; |
92 | extern long long epoll_intr; |
93 | extern long long event_timer_insert_ops; |
94 | extern long long event_timer_remove_ops; |
95 | |
96 | extern long long long_queries_cnt; |
97 | extern long long long_cpu_queries_cnt; |
98 | |
99 | int prepare_stats (char *buff, int buff_size) { |
100 | if (buff_size <= 0) { |
101 | /* (SIGSEGV guard) */ |
102 | /* in snprintf function second arg type is size_t */ |
103 | return 0; |
104 | } |
105 | double um = get_utime_monotonic (); |
106 | stats_buffer_t sb; |
107 | sb_init (&sb, buff, buff_size); |
108 | |
109 | if (!my_pid) { |
110 | my_pid = getpid (); |
111 | } |
112 | int uptime = now - start_time; |
113 | |
114 | sb_printf (&sb, |
115 | "pid\t%d\n" |
116 | "start_time\t%d\n" |
117 | "current_time\t%d\n" |
118 | "uptime\t%d\n" |
119 | "tot_idle_time\t%.3f\n" |
120 | "average_idle_percent\t%.3f\n" |
121 | "recent_idle_percent\t%.3f\n" |
122 | "active_network_events\t%d\n" |
123 | "time_after_epoll\t%.6f\n" |
124 | "epoll_calls\t%lld\n" |
125 | "epoll_intr\t%lld\n" |
126 | "PID\t" PID_PRINT_STR "\n" |
127 | , |
128 | my_pid, |
129 | start_time, |
130 | now, |
131 | uptime, |
132 | tot_idle_time, |
133 | uptime > 0 ? tot_idle_time / uptime * 100 : 0, |
134 | a_idle_quotient > 0 ? a_idle_time / a_idle_quotient * 100 : a_idle_time, |
135 | ev_heap_size, |
136 | get_utime (CLOCK_MONOTONIC) - last_epoll_wait_at, |
137 | epoll_calls, |
138 | epoll_intr, |
139 | PID_TO_PRINT (&PID) |
140 | ); |
141 | |
142 | |
143 | connections_prepare_stat (&sb); |
144 | raw_msg_prepare_stat (&sb); |
145 | raw_msg_buffer_prepare_stat (&sb); |
146 | tl_parse_prepare_stat (&sb); |
147 | crypto_aes_prepare_stat (&sb); |
148 | crypto_dh_prepare_stat (&sb); |
149 | jobs_prepare_stat (&sb); |
150 | mp_queue_prepare_stat (&sb); |
151 | timers_prepare_stat (&sb); |
152 | rpc_targets_prepare_stat (&sb); |
153 | |
154 | sb_printf (&sb, |
155 | "stats_generate_time\t%.6f\n" , |
156 | get_utime_monotonic () - um); |
157 | return sb.pos; |
158 | } |
159 | |
160 | void output_std_stats (void) { |
161 | static char debug_stats[1 << 20]; |
162 | int len = prepare_stats (debug_stats, sizeof (debug_stats) - 1); |
163 | if (len > 0) { |
164 | kprintf ("-------------- network statistics ------------\n%s\n-------------------------------------\n" , debug_stats); |
165 | } |
166 | } |
167 | |