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
55struct process_id PID;
56
57extern int zheap_debug;
58long long queries_allocated;
59long long max_queries_allocated;
60long long max_queries_allocated_sec;
61long long max_queries_allocated_prev_sec;
62
63long long total_vv_tree_nodes;
64
65int tl_rpc_op_stat __attribute__ ((weak));
66int op_stat_write (stats_buffer_t *sb) __attribute__ ((weak));
67int op_stat_write (stats_buffer_t *sb) { return 0; }
68
69
70int my_pid;
71
72int connections_prepare_stat (stats_buffer_t *sb);
73int udp_prepare_stat (stats_buffer_t *sb);
74int tl_parse_prepare_stat (stats_buffer_t *sb);
75int raw_msg_prepare_stat (stats_buffer_t *sb);
76int raw_msg_buffer_prepare_stat (stats_buffer_t *sb);
77int crypto_aes_prepare_stat (stats_buffer_t *sb);
78int crypto_dh_prepare_stat (stats_buffer_t *sb);
79int jobs_prepare_stat (stats_buffer_t *sb);
80int aio_prepare_stat (stats_buffer_t *sb);
81int mp_queue_prepare_stat (stats_buffer_t *sb);
82int timers_prepare_stat (stats_buffer_t *sb);
83int 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
87int recent_idle_percent (void) {
88 return a_idle_quotient > 0 ? a_idle_time / a_idle_quotient * 100 : a_idle_time;
89}
90
91extern long long epoll_calls;
92extern long long epoll_intr;
93extern long long event_timer_insert_ops;
94extern long long event_timer_remove_ops;
95
96extern long long long_queries_cnt;
97extern long long long_cpu_queries_cnt;
98
99int 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
160void 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