1 /*
2  * Copyright (C) 2021 Jakub Kruszona-Zawadzki, Core Technology Sp. z o.o.
3  *
4  * This file is part of MooseFS.
5  *
6  * MooseFS is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, version 2 (only).
9  *
10  * MooseFS is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with MooseFS; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02111-1301, USA
18  * or visit http://www.gnu.org/licenses/gpl-2.0.html
19  */
20 
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24 
25 #include <time.h>
26 #include <stdlib.h>
27 #include <stdio.h>
28 #include <string.h>
29 #include <unistd.h>
30 #include <fcntl.h>
31 #include <syslog.h>
32 #include <errno.h>
33 
34 
35 #include "charts.h"
36 #include "main.h"
37 
38 #include "chunks.h"
39 #include "filesystem.h"
40 #include "matoclserv.h"
41 #include "memusage.h"
42 #include "cpuusage.h"
43 #include "matocsserv.h"
44 
45 #include "chartsdefs.h"
46 
47 #if 0
48 #define CHARTS_FILENAME "stats.mfs"
49 
50 #define CHARTS_UCPU 0
51 #define CHARTS_SCPU 1
52 #define CHARTS_DELCHUNK 2
53 #define CHARTS_REPLCHUNK 3
54 #define CHARTS_STATFS 4
55 #define CHARTS_GETATTR 5
56 #define CHARTS_SETATTR 6
57 #define CHARTS_LOOKUP 7
58 #define CHARTS_MKDIR 8
59 #define CHARTS_RMDIR 9
60 #define CHARTS_SYMLINK 10
61 #define CHARTS_READLINK 11
62 #define CHARTS_MKNOD 12
63 #define CHARTS_UNLINK 13
64 #define CHARTS_RENAME 14
65 #define CHARTS_LINK 15
66 #define CHARTS_READDIR 16
67 #define CHARTS_OPEN 17
68 #define CHARTS_READ 18
69 #define CHARTS_WRITE 19
70 #define CHARTS_MEMORY_RSS 20
71 #define CHARTS_PACKETSRCVD 21
72 #define CHARTS_PACKETSSENT 22
73 #define CHARTS_BYTESRCVD 23
74 #define CHARTS_BYTESSENT 24
75 #define CHARTS_MEMORY_VIRT 25
76 
77 #define CHARTS 26
78 
79 /* name , join mode , percent , scale , multiplier , divisor */
80 #define STATDEFS { \
81 	{"ucpu"         ,CHARTS_MODE_ADD,1,CHARTS_SCALE_MICRO, 100,60}, \
82 	{"scpu"         ,CHARTS_MODE_ADD,1,CHARTS_SCALE_MICRO, 100,60}, \
83 	{"delete"       ,CHARTS_MODE_ADD,0,CHARTS_SCALE_NONE ,   1, 1}, \
84 	{"replicate"    ,CHARTS_MODE_ADD,0,CHARTS_SCALE_NONE ,   1, 1}, \
85 	{"statfs"       ,CHARTS_MODE_ADD,0,CHARTS_SCALE_NONE ,   1, 1}, \
86 	{"getattr"      ,CHARTS_MODE_ADD,0,CHARTS_SCALE_NONE ,   1, 1}, \
87 	{"setattr"      ,CHARTS_MODE_ADD,0,CHARTS_SCALE_NONE ,   1, 1}, \
88 	{"lookup"       ,CHARTS_MODE_ADD,0,CHARTS_SCALE_NONE ,   1, 1}, \
89 	{"mkdir"        ,CHARTS_MODE_ADD,0,CHARTS_SCALE_NONE ,   1, 1}, \
90 	{"rmdir"        ,CHARTS_MODE_ADD,0,CHARTS_SCALE_NONE ,   1, 1}, \
91 	{"symlink"      ,CHARTS_MODE_ADD,0,CHARTS_SCALE_NONE ,   1, 1}, \
92 	{"readlink"     ,CHARTS_MODE_ADD,0,CHARTS_SCALE_NONE ,   1, 1}, \
93 	{"mknod"        ,CHARTS_MODE_ADD,0,CHARTS_SCALE_NONE ,   1, 1}, \
94 	{"unlink"       ,CHARTS_MODE_ADD,0,CHARTS_SCALE_NONE ,   1, 1}, \
95 	{"rename"       ,CHARTS_MODE_ADD,0,CHARTS_SCALE_NONE ,   1, 1}, \
96 	{"link"         ,CHARTS_MODE_ADD,0,CHARTS_SCALE_NONE ,   1, 1}, \
97 	{"readdir"      ,CHARTS_MODE_ADD,0,CHARTS_SCALE_NONE ,   1, 1}, \
98 	{"open"         ,CHARTS_MODE_ADD,0,CHARTS_SCALE_NONE ,   1, 1}, \
99 	{"read"         ,CHARTS_MODE_ADD,0,CHARTS_SCALE_NONE ,   1, 1}, \
100 	{"write"        ,CHARTS_MODE_ADD,0,CHARTS_SCALE_NONE ,   1, 1}, \
101 	{"memoryrss"    ,CHARTS_MODE_MAX,0,CHARTS_SCALE_NONE ,   1, 1}, \
102 	{"prcvd"        ,CHARTS_MODE_ADD,0,CHARTS_SCALE_MILI ,1000,60}, \
103 	{"psent"        ,CHARTS_MODE_ADD,0,CHARTS_SCALE_MILI ,1000,60}, \
104 	{"brcvd"        ,CHARTS_MODE_ADD,0,CHARTS_SCALE_MILI ,8000,60}, \
105 	{"bsent"        ,CHARTS_MODE_ADD,0,CHARTS_SCALE_MILI ,8000,60}, \
106 	{"memoryvirt"   ,CHARTS_MODE_MAX,0,CHARTS_SCALE_NONE ,   1, 1}, \
107 	{NULL           ,0              ,0,0                 ,   0, 0}  \
108 };
109 
110 #define CALCDEFS { \
111 	CHARTS_CALCDEF(CHARTS_MAX(CHARTS_CONST(0),CHARTS_SUB(CHARTS_MEMORY_VIRT,CHARTS_MEMORY_RSS))), \
112 	CHARTS_DEFS_END \
113 };
114 
115 /* c1_def , c2_def , c3_def , join mode , percent , scale , multiplier , divisor */
116 #define ESTATDEFS { \
117 	{CHARTS_DIRECT(CHARTS_UCPU)        ,CHARTS_DIRECT(CHARTS_SCPU)            ,CHARTS_NONE                       ,CHARTS_MODE_ADD,1,CHARTS_SCALE_MICRO, 100,60}, \
118 	{CHARTS_CALC(0)                    ,CHARTS_DIRECT(CHARTS_MEMORY_RSS)      ,CHARTS_NONE                       ,CHARTS_MODE_MAX,0,CHARTS_SCALE_NONE ,   1, 1}, \
119 	{CHARTS_NONE                       ,CHARTS_NONE                           ,CHARTS_NONE                       ,0              ,0,0                 ,   0, 0}  \
120 };
121 #endif
122 static const uint32_t calcdefs[]=CALCDEFS
123 static const statdef statdefs[]=STATDEFS
124 static const estatdef estatdefs[]=ESTATDEFS
125 
126 static uint64_t rss,virt;
127 static uint64_t scpu,ucpu;
128 
chartsdata_resusage(uint64_t * mem,uint64_t * syscpu,uint64_t * usrcpu)129 void chartsdata_resusage(uint64_t *mem,uint64_t *syscpu,uint64_t *usrcpu) {
130 	*mem = rss;
131 	*syscpu = scpu;
132 	*usrcpu = ucpu;
133 }
134 
chartsdata_refresh(void)135 void chartsdata_refresh(void) {
136 	uint64_t data[CHARTS];
137 	uint32_t fsdata[16];
138 	uint32_t chunkops[12];
139 	uint32_t i;
140 	uint64_t total,avail;
141 
142 	for (i=0 ; i<CHARTS ; i++) {
143 		data[i]=CHARTS_NODATA;
144 	}
145 
146 	cpu_used(&scpu,&ucpu);
147 	if (scpu>0 || ucpu>0) {
148 		data[CHARTS_UCPU] = (ucpu*6)/100;
149 		data[CHARTS_SCPU] = (scpu*6)/100;
150 	}
151 
152 	if (mem_used(&rss,&virt)) {
153 		data[CHARTS_MEMORY_RSS] = rss;
154 		data[CHARTS_MEMORY_VIRT] = virt;
155 	}
156 
157 	chunk_stats(chunkops);
158 	data[CHARTS_DELCHUNK]=chunkops[CHUNK_OP_DELETE_TRY];
159 	data[CHARTS_REPLCHUNK]=chunkops[CHUNK_OP_REPLICATE_TRY];
160 	data[CHARTS_CREATECHUNK]=chunkops[CHUNK_OP_CREATE_TRY];
161 	data[CHARTS_CHANGECHUNK]=chunkops[CHUNK_OP_CHANGE_TRY];
162 	data[CHARTS_DELETECHUNK_OK]=chunkops[CHUNK_OP_DELETE_OK];
163 	data[CHARTS_REPLICATECHUNK_OK]=chunkops[CHUNK_OP_REPLICATE_OK];
164 	data[CHARTS_CREATECHUNK_OK]=chunkops[CHUNK_OP_CREATE_OK];
165 	data[CHARTS_CHANGECHUNK_OK]=chunkops[CHUNK_OP_CHANGE_OK];
166 	data[CHARTS_DELETECHUNK_ERR]=chunkops[CHUNK_OP_DELETE_ERR];
167 	data[CHARTS_REPLICATECHUNK_ERR]=chunkops[CHUNK_OP_REPLICATE_ERR];
168 	data[CHARTS_CREATECHUNK_ERR]=chunkops[CHUNK_OP_CREATE_ERR];
169 	data[CHARTS_CHANGECHUNK_ERR]=chunkops[CHUNK_OP_CHANGE_ERR];
170 
171 	fs_stats(fsdata);
172 	for (i=0 ; i<16 ; i++) {
173 		data[CHARTS_STATFS+i]=fsdata[i];
174 	}
175 	matoclserv_stats(data+CHARTS_PACKETSRCVD);
176 
177 	matocsserv_getspace(&total,&avail,NULL);
178 	data[CHARTS_USED_SPACE]=total-avail;
179 	data[CHARTS_TOTAL_SPACE]=total;
180 
181 	charts_add(data,main_time()-60);
182 }
183 
chartsdata_term(void)184 void chartsdata_term(void) {
185 	chartsdata_refresh();
186 	charts_store();
187 	charts_term();
188 }
189 
chartsdata_store(void)190 void chartsdata_store(void) {
191 	charts_store();
192 }
193 
chartsdata_init(void)194 int chartsdata_init (void) {
195 	cpu_init();
196 	scpu = ucpu = 0;
197 	mem_used(&rss,&virt);
198 
199 	main_time_register(60,0,chartsdata_refresh);
200 	main_time_register(3600,30,chartsdata_store);
201 	main_destruct_register(chartsdata_term);
202 	return charts_init(calcdefs,statdefs,estatdefs,CHARTS_FILENAME,0);
203 }
204