1 /*****************************************************************************
2 * RRDtool 1.0.33 Copyright Tobias Oetiker, 1997 - 2000
3 *****************************************************************************
4 * rrd_stat Retreive the header part of an RRD
5 *****************************************************************************/
7 #include "rrd_tool.h"
9 extern char *tzname[2];
11 stat_node
12 rrd_stat(int argc, char **argv)
13 {
14 int i,ii,ix,iii=0;
15 time_t now;
16 char somestring[255];
17 rrd_value_t my_cdp;
18 long rra_base, rra_start, rra_next;
19 FILE *in_file;
20 rrd_t rrd;
23 if(rrd_open(argv[1],&in_file,&rrd, RRD_READONLY)==-1){
24 return(-1);
25 }
26 puts("<!-- Round Robin Database Dump -->");
27 puts("<rrd>");
28 printf("\t<version> %s </version>\n",rrd.stat_head->version);
29 printf("\t<step> %lu </step> <!-- Seconds -->\n",rrd.stat_head->pdp_step);
30 #if HAVE_STRFTIME
31 strftime(somestring,200,"%Y-%m-%d %H:%M:%S %Z",
32 localtime(&rrd.live_head->last_up));
33 #else
34 # error "Need strftime"
35 #endif
36 printf("\t<lastupdate> %ld </lastupdate> <!-- %s -->\n\n",
37 rrd.live_head->last_up,somestring);
38 for(i=0;i<rrd.stat_head->ds_cnt;i++){
39 printf("\t<ds>\n");
40 printf("\t\t<name> %s </name>\n",rrd.ds_def[i].ds_nam);
41 printf("\t\t<type> %s </type>\n",rrd.ds_def[i].dst);
42 printf("\t\t<minimal_heartbeat> %lu </minimal_heartbeat>\n",
43 rrd.ds_def[i].par[DS_mrhb_cnt].u_cnt);
44 if (isnan(rrd.ds_def[i].par[DS_min_val].u_val)){
45 printf("\t\t<min> NaN </min>\n");
46 } else {
47 printf("\t\t<min> %0.10e </min>\n",rrd.ds_def[i].par[DS_min_val].u_val);
48 }
49 if (isnan(rrd.ds_def[i].par[DS_max_val].u_val)){
50 printf("\t\t<max> NaN </max>\n");
51 } else {
52 printf("\t\t<max> %0.10e </max>\n",rrd.ds_def[i].par[DS_max_val].u_val);
53 }
54 printf("\n\t\t<!-- PDP Status -->\n");
55 printf("\t\t<last_ds> %s </last_ds>\n",rrd.pdp_prep[i].last_ds);
56 if (isnan(rrd.pdp_prep[i].scratch[PDP_val].u_val)){
57 printf("\t\t<value> NaN </value>\n");
58 } else {
59 printf("\t\t<value> %0.10e </value>\n",rrd.pdp_prep[i].scratch[PDP_val].u_val);
60 }
61 printf("\t\t<unknown_sec> %lu </unknown_sec>\n",
62 rrd.pdp_prep[i].scratch[PDP_unkn_sec_cnt].u_cnt);
64 printf("\t</ds>\n\n");
65 }
67 puts("<!-- Round Robin Archives -->");
69 rra_base=ftell(in_file);
70 rra_next = rra_base;
72 for(i=0;i<rrd.stat_head->rra_cnt;i++){
74 long timer=0;
75 rra_start= rra_next;
76 rra_next += ( rrd.stat_head->ds_cnt
77 * rrd.rra_def[i].row_cnt
78 * sizeof(rrd_value_t));
79 printf("\t<rra>\n");
80 printf("\t\t<cf> %s </cf>\n",rrd.rra_def[i].cf_nam);
81 printf("\t\t<pdp_per_row> %lu </pdp_per_row> <!-- %lu seconds -->\n\n",
82 rrd.rra_def[i].pdp_cnt, rrd.rra_def[i].pdp_cnt
83 *rrd.stat_head->pdp_step);
84 printf("\t\t<cdp_prep>\n");
85 for(ii=0;ii<rrd.stat_head->ds_cnt;ii++){
86 double value = rrd.cdp_prep[i*rrd.stat_head->ds_cnt+ii].scratch[CDP_val].u_val;
87 printf("\t\t\t<ds>");
88 if (isnan(value)){
89 printf("<value> NaN </value>");
90 } else {
91 printf("<value> %0.10e </value>", value);
92 }
93 printf(" <unknown_datapoints> %lu </unknown_datapoints>",
94 rrd.cdp_prep[i*rrd.stat_head->ds_cnt+ii].scratch[CDP_unkn_pdp_cnt].u_cnt);
95 printf("</ds>\n");
96 }
97 printf("\t\t</cdp_prep>\n");
99 printf("\t\t<database>\n");
100 fseek(in_file,(rra_start
101 +(rrd.rra_ptr[i].cur_row+1)
102 * rrd.stat_head->ds_cnt
103 * sizeof(rrd_value_t)),SEEK_SET);
104 timer = - (rrd.rra_def[i].row_cnt-1);
105 ii=rrd.rra_ptr[i].cur_row;
106 for(ix=0;ix<rrd.rra_def[i].row_cnt;ix++){
107 ii++;
108 if (ii>=rrd.rra_def[i].row_cnt) {
109 fseek(in_file,rra_start,SEEK_SET);
110 ii=0; /* wrap if max row cnt is reached */
111 }
112 now = (rrd.live_head->last_up
113 - rrd.live_head->last_up
114 % (rrd.rra_def[i].pdp_cnt*rrd.stat_head->pdp_step))
115 + (timer*rrd.rra_def[i].pdp_cnt*rrd.stat_head->pdp_step);
117 timer++;
118 #if HAVE_STRFTIME
119 strftime(somestring,200,"%Y-%m-%d %H:%M:%S %Z", localtime(&now));
120 #else
121 # error "Need strftime"
122 #endif
123 printf("\t\t\t<!-- %s --> <row>",somestring);
124 for(iii=0;iii<rrd.stat_head->ds_cnt;iii++){
125 fread(&my_cdp,sizeof(rrd_value_t),1,in_file);
126 if (isnan(my_cdp)){
127 printf("<v> NaN </v>");
128 } else {
129 printf("<v> %0.10e </v>",my_cdp);
130 };
131 }
132 printf("</row>\n");
133 }
134 printf("\t\t</database>\n\t</rra>\n");
136 }
137 printf("</rrd>\n");
138 rrd_free(&rrd);
139 fclose(in_file);
140 return(0);
141 }