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