* progress in moving all the fileaccess over to a wrapper system that can do fd based...
[rrdtool.git] / src / rrd_stat.c
1 /*****************************************************************************
2  * RRDtool 1.2.23  Copyright by Tobi Oetiker, 1997-2007
3  *****************************************************************************
4  * rrd_stat Retreive the header part of an RRD
5  *****************************************************************************/
6
7 #include "rrd_tool.h"
8
9 XXX: This file is not compiled. Is this on purpose?
10
11 extern char *tzname[2];
12
13 stat_node
14 rrd_stat(int argc, char **argv)    
15 {   
16     int          i,ii,ix,iii=0;
17     time_t       now;
18     char         somestring[255];
19     rrd_value_t  my_cdp;
20     long         rra_base, rra_start, rra_next;
21     rrd_t             rrd;
22     rrd_file_t  *rrd_file;
23
24
25     rrd_file = rrd_open(argv[1],&rrd, RRD_READONLY);
26     if (rrd_file == NULL) {
27         return(-1);
28     }
29     puts("<!-- Round Robin Database Dump -->");
30     puts("<rrd>");
31     printf("\t<version> %s </version>\n",rrd.stat_head->version);
32     printf("\t<step> %lu </step> <!-- Seconds -->\n",rrd.stat_head->pdp_step);
33 #if HAVE_STRFTIME
34     strftime(somestring,200,"%Y-%m-%d %H:%M:%S %Z",
35              localtime_r(&rrd.live_head->last_up, &tm));
36 #else
37 # error "Need strftime"
38 #endif
39     printf("\t<lastupdate> %ld </lastupdate> <!-- %s -->\n\n",
40            rrd.live_head->last_up,somestring);
41     for(i=0;i<rrd.stat_head->ds_cnt;i++){
42         printf("\t<ds>\n");
43         printf("\t\t<name> %s </name>\n",rrd.ds_def[i].ds_nam);
44         printf("\t\t<type> %s </type>\n",rrd.ds_def[i].dst);
45         printf("\t\t<minimal_heartbeat> %lu </minimal_heartbeat>\n",
46                rrd.ds_def[i].par[DS_mrhb_cnt].u_cnt);
47         if (isnan(rrd.ds_def[i].par[DS_min_val].u_val)){
48           printf("\t\t<min> NaN </min>\n");
49         } else {
50           printf("\t\t<min> %0.10e </min>\n",rrd.ds_def[i].par[DS_min_val].u_val);
51         }
52         if (isnan(rrd.ds_def[i].par[DS_max_val].u_val)){
53           printf("\t\t<max> NaN </max>\n");
54         } else {
55           printf("\t\t<max> %0.10e </max>\n",rrd.ds_def[i].par[DS_max_val].u_val);
56         }
57         printf("\n\t\t<!-- PDP Status -->\n");
58         printf("\t\t<last_ds> %s </last_ds>\n",rrd.pdp_prep[i].last_ds);
59         if (isnan(rrd.pdp_prep[i].scratch[PDP_val].u_val)){
60           printf("\t\t<value> NaN </value>\n");
61         } else {
62           printf("\t\t<value> %0.10e </value>\n",rrd.pdp_prep[i].scratch[PDP_val].u_val);
63         }
64         printf("\t\t<unknown_sec> %lu </unknown_sec>\n",
65                rrd.pdp_prep[i].scratch[PDP_unkn_sec_cnt].u_cnt);
66         
67         printf("\t</ds>\n\n");
68     }
69
70     puts("<!-- Round Robin Archives -->");
71
72     rra_base = rrd_file->header_len;
73     rra_next = rra_base;
74
75     for(i=0;i<rrd.stat_head->rra_cnt;i++){
76         
77         long timer=0;
78         rra_start= rra_next;
79         rra_next +=  ( rrd.stat_head->ds_cnt
80                       * rrd.rra_def[i].row_cnt
81                       * sizeof(rrd_value_t));
82         printf("\t<rra>\n");
83         printf("\t\t<cf> %s </cf>\n",rrd.rra_def[i].cf_nam);
84         printf("\t\t<pdp_per_row> %lu </pdp_per_row> <!-- %lu seconds -->\n\n",
85                rrd.rra_def[i].pdp_cnt, rrd.rra_def[i].pdp_cnt
86                *rrd.stat_head->pdp_step);
87         printf("\t\t<cdp_prep>\n");
88         for(ii=0;ii<rrd.stat_head->ds_cnt;ii++){
89             double value = rrd.cdp_prep[i*rrd.stat_head->ds_cnt+ii].scratch[CDP_val].u_val;
90             printf("\t\t\t<ds>");       
91             if (isnan(value)){
92               printf("<value> NaN </value>");
93             } else {
94               printf("<value> %0.10e </value>", value);
95             }
96             printf("  <unknown_datapoints> %lu </unknown_datapoints>",
97                    rrd.cdp_prep[i*rrd.stat_head->ds_cnt+ii].scratch[CDP_unkn_pdp_cnt].u_cnt);
98            printf("</ds>\n");    
99         }
100         printf("\t\t</cdp_prep>\n");
101
102         printf("\t\t<database>\n");
103         rrd_seek(rrd_file,(rra_start
104                        +(rrd.rra_ptr[i].cur_row+1)
105                        * rrd.stat_head->ds_cnt
106                        * sizeof(rrd_value_t)),SEEK_SET);
107         timer = - (rrd.rra_def[i].row_cnt-1);
108         ii=rrd.rra_ptr[i].cur_row;
109         for(ix=0;ix<rrd.rra_def[i].row_cnt;ix++){           
110             ii++;
111             if (ii>=rrd.rra_def[i].row_cnt) {
112                 rrd_seek(rrd_file,rra_start,SEEK_SET);
113                 ii=0; /* wrap if max row cnt is reached */
114             }
115             now = (rrd.live_head->last_up 
116                    - rrd.live_head->last_up 
117                    % (rrd.rra_def[i].pdp_cnt*rrd.stat_head->pdp_step)) 
118                 + (timer*rrd.rra_def[i].pdp_cnt*rrd.stat_head->pdp_step);
119
120             timer++;
121 #if HAVE_STRFTIME
122             strftime(somestring,200,"%Y-%m-%d %H:%M:%S %Z", localtime_r(&now, &tm));
123 #else
124 # error "Need strftime"
125 #endif
126             printf("\t\t\t<!-- %s --> <row>",somestring);
127             for(iii=0;iii<rrd.stat_head->ds_cnt;iii++){                  
128                 rrd_read(rrd_file,&my_cdp,sizeof(rrd_value_t)*1);
129                 if (isnan(my_cdp)){
130                   printf("<v> NaN </v>");
131                 } else {
132                   printf("<v> %0.10e </v>",my_cdp);
133                 };
134             }
135             printf("</row>\n");
136         }
137         printf("\t\t</database>\n\t</rra>\n");
138         
139     }
140     printf("</rrd>\n");
141     rrd_free(&rrd);
142     close(rrd_file->fd);
143     return(0);
144 }
145
146
147
148