started updating for 1.2 release
[rrdtool.git] / src / rrd_stat.c
1 /*****************************************************************************
2  * RRDtool 1.2rc6  Copyright by Tobi Oetiker, 1997-2005
3  *****************************************************************************
4  * rrd_stat Retreive the header part of an RRD
5  *****************************************************************************/
6
7 #include "rrd_tool.h"
8
9 extern char *tzname[2];
10
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;
21
22
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_r(&rrd.live_head->last_up, &tm));
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);
63         
64         printf("\t</ds>\n\n");
65     }
66
67     puts("<!-- Round Robin Archives -->");
68
69     rra_base=ftell(in_file);    
70     rra_next = rra_base;
71
72     for(i=0;i<rrd.stat_head->rra_cnt;i++){
73         
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");
98
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);
116
117             timer++;
118 #if HAVE_STRFTIME
119             strftime(somestring,200,"%Y-%m-%d %H:%M:%S %Z", localtime_r(&now, &tm));
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");
135         
136     }
137     printf("</rrd>\n");
138     rrd_free(&rrd);
139     fclose(in_file);
140     return(0);
141 }
142
143
144
145