rvm  1.11
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
reporter.cc
Go to the documentation of this file.
1 #include "config.h"
2 
3 #include <iostream>
4 #include <string>
5 #include <vector>
6 #include <algorithm>
7 
8 #include "asserts.h"
9 #include "error.h"
10 #include "estring.h"
11 #include "fs.h"
12 #include "rconfig.h"
13 #include "timer.h"
14 #include "logger.h"
15 #include "estat.h"
16 #include "vaulter.h"
17 #include "strfmt.h"
18 #include "archiver.h"
19 #include "table.h"
20 
21 #include "reporter.h"
22 
23 //-----------------------------------------------------------------------------
24 
25 /** C'tor */
27 {
28  clear();
29 }
30 
31 /** C'tor */
33 {
34  clear();
35  assign(a_class);
36 }
37 
38 /** C'tor */
40  const std::string& a_message,
41  const filesystem& a_class
42  )
43 {
44  clear();
45  assign(a_message,a_class);
46 }
47 
48 /** D'tor */
50 {
51 }
52 
53 /** Clear all values */
55 {
56  m_total_blocks = 0;
57  m_free_blocks = 0;
58  m_total_inodes = 0;
59  m_free_inodes = 0;
60 }
61 
62 /** Assignment */
64  const vault_stats_report& a_class
65  )
66 {
67  assign(
68  a_class.message(),
69  a_class.time(),
70  a_class.total_blocks(),
71  a_class.free_blocks(),
72  a_class.total_inodes(),
73  a_class.free_inodes()
74  );
75 }
76 
77 /** Assignment */
79  const std::string& a_message,
80  const filesystem& a_class
81  )
82 {
83  assign(
84  a_message,
85  current_time(),
86  a_class.total_blocks(),
87  a_class.free_blocks(),
88  a_class.total_inodes(),
89  a_class.free_inodes()
90  );
91 }
92 
93 /** Assignment */
95  const std::string& a_message,
96  const std::string& a_time,
97  const uint64 a_total_blocks,
98  const uint64 a_free_blocks,
99  const uint64 a_total_inodes,
100  const uint64 a_free_inodes
101  )
102 {
103  TRY_nomem(m_message = a_message);
104  m_total_blocks = a_total_blocks;
105  m_free_blocks = a_free_blocks;
106  m_total_inodes = a_total_inodes;
107  m_free_inodes = a_free_inodes;
108 
109  TRY_nomem(m_time = a_time);
110 }
111 
112 /** Return a string timestamp */
113 const std::string& vault_stats_report::time(void) const
114 {
115  return(m_time);
116 }
117 
118 /** Return the message */
119 const std::string& vault_stats_report::message(void) const
120 {
121  return(m_message);
122 }
123 
124 /** Return the total number of blocks in the vault */
125 const uint64 vault_stats_report::total_blocks(void) const
126 {
127  return(m_total_blocks);
128 }
129 
130 /** Return the number of free blocks in the vault */
131 const uint64 vault_stats_report::free_blocks(void) const
132 {
133  return(m_free_blocks);
134 }
135 
136 /** Return the total number of inodes in the vault */
137 const uint64 vault_stats_report::total_inodes(void) const
138 {
139  return(m_total_inodes);
140 }
141 
142 /** Return the number of free inodes in the vault */
143 const uint64 vault_stats_report::free_inodes(void) const
144 {
145  return(m_free_inodes);
146 }
147 
148 /** Assignment operator */
151 {
152  assign(a_class);
153  return(*this);
154 }
155 
156 //-----------------------------------------------------------------------------
157 
158 /** C'tor */
160 {
161  clear();
162 }
163 
164 /** D'tor */
166 {
167 }
168 
169 /** Clear all values */
171 {
172  m_reports.clear();
173 }
174 
175 /** Add a vault report to the list */
177  const vault_stats_report& a_class
178  )
179 {
180  TRY_nomem(m_reports.push_back(a_class));
181 }
182 
183 /** Format and print the vault report to the given stream */
184 void vault_report::write_report(std::ostream& out)
185 {
186  table tab, tab2;
187  estring estr;
188  std::vector<vault_stats_report>::const_iterator vi;
189  uint64 ui64b, ui64e, ui64t;
190 
191  estr = "Vault Statistics";
192  estr.align(estring::center);
193  tab << estr << table_endl;
194 
195  estr = "";
196  estr.fillchar('-');
197  estr.align(estring::left);
198  tab << estr << table_endl;
199 
200  // Header
201  tab2
202  << "Time"
203  << " "
204  << "Message"
205  << " "
206  << "Free Blocks"
207  << " "
208  << "Free Inodes"
209  << " "
210  << table_endl;
211 
212  // Separators
213  estr.align(estring::left);
214  estr.fillchar('-');
215  estr = "";
216  tab2
217  << estr
218  << " "
219  << estr
220  << " "
221  << estr
222  << " "
223  << estr
224  << table_endl;
225 
226  // Vault messages/statistics
227  estr.fillchar(' ');
228  for (vi = m_reports.begin(); vi != m_reports.end(); ++vi) {
229  tab2
230  << vi->time()
231  << " ";
232 
233  estr.align(estring::right);
234  estr = vi->message();
235  tab2 << estr;
236 
237  tab2 << " ";
238 
239  estr.align(estring::center);
240 
241  estr = " ";
242  estr += percent_string(vi->free_blocks(), vi->total_blocks());
243  tab2 << estr;
244 
245  tab2 << " ";
246 
247  estr = " ";
248  estr += percent_string(vi->free_inodes(), vi->total_inodes());
249  tab2 << estr;
250 
251  tab2 << table_endl;
252  }
253 
254  // Separators
255  estr.align(estring::left);
256  estr.fillchar('-');
257  estr = "";
258  tab2
259  << " "
260  << " "
261  << " "
262  << " "
263  << estr
264  << " "
265  << estr
266  << table_endl;
267 
268  // Final
269  estr.align(estring::right);
270  estr.fillchar(' ');
271  estr = "Total Difference:";
272  // estr.align(estring::center);
273  // estr.fillchar(' ');
274  tab2
275  << " "
276  << " "
277  << estr
278  << " ";
279 
280  estr.align(estring::center);
281  ASSERT(m_reports.size() > 0);
282  ui64b = m_reports[0].free_blocks();
283  ui64e = m_reports[m_reports.size()-1].free_blocks();
284  ui64t = m_reports[0].total_blocks();
285  if (ui64b > ui64e) {
286  estr = "-";
287  estr += percent_string(ui64b - ui64e, ui64t);
288  }
289  else {
290  estr = "+";
291  estr += percent_string(ui64e - ui64b, ui64t);
292  }
293  tab2 << estr;
294 
295  tab2 << " ";
296 
297  ui64b = m_reports[0].free_inodes();
298  ui64e = m_reports[m_reports.size()-1].free_inodes();
299  ui64t = m_reports[0].total_inodes();
300  if (ui64b > ui64e) {
301  estr = "-";
302  estr += percent_string(ui64b - ui64e, ui64t);
303  }
304  else {
305  estr = "+";
306  estr += percent_string(ui64e - ui64b, ui64t);
307  }
308  tab2 << estr;
309 
310  tab2 << table_endl;
311 
312  tab << tab2;
313 
314  out << tab;
315 }
316 
317 /** Generate a synopsis report */
319 {
320  estring estr;
321 
322  estr.align(estring::right);
323  estr = "Timestamp:";
324  a_table << estr << " " << config.timestamp().str() << table_endl;
325 
326  estr = "Vault Selected:";
327  a_table << estr << " " << vaulter.vault() << table_endl;
328 }
329 
330 //-----------------------------------------------------------------------------
331 
332 /** C'tor */
334 {
335  clear();
336 }
337 
338 /** C'tor */
340 {
341  clear();
342  assign(a_class);
343 }
344 
345 /** C'tor */
347  const std::string a_source,
348  const timer a_time,
349  const uint16 a_exit_code,
350  const uint16 a_signal_num,
351  const rsync_behavior::value_type a_behavior,
352  const std::string a_error_message
353  )
354 {
355  clear();
356  assign(
357  a_source,
358  a_time,
359  a_exit_code,
360  a_signal_num,
361  a_behavior,
362  a_error_message
363  );
364 }
365 
366 /** D'tor */
368 {
369 }
370 
371 /** Clear all values */
373 {
374  m_source.erase();
375  m_time.clear();
376  m_exit_code = 0;
377  m_signal_num = 0;
378  m_error_msg.erase();
380 }
381 
382 /** Assignment */
384 {
385  assign(
386  a_class.m_source,
387  a_class.m_time,
388  a_class.m_exit_code,
389  a_class.m_signal_num,
390  a_class.m_behavior,
391  a_class.m_error_msg
392  );
393 }
394 
395 /** Assignment */
397  const std::string a_source,
398  const timer a_time,
399  const uint16 a_exit_code,
400  const uint16 a_signal_num,
401  const rsync_behavior::value_type a_behavior,
402  const std::string a_error_message
403  )
404 {
405  TRY_nomem(m_source = a_source);
406  TRY_nomem(m_error_msg = a_error_message);
407  TRY_nomem(m_time = a_time);
408  m_exit_code = a_exit_code;
409  m_signal_num = a_signal_num;
410  m_behavior = a_behavior;
411 }
412 
413 /** Return true if rsync succeeded archiving this path */
414 const bool job_path_report::status(void) const
415 {
416 // std::cerr << "[DEBUG]: job_path_report::status()" << std::endl;
417 // std::cerr << "[DEBUG]: m_source = " << m_source << std::endl;
418 // std::cerr << "[DEBUG]: m_exit_code = " << m_exit_code << std::endl;
419 // std::cerr << "[DEBUG]: m_signal_num = " << m_signal_num << std::endl;
420 // std::cerr << "[DEBUG]: m_error_msg = " << m_error_msg << std::endl;
421 // std::cerr << "[DEBUG]: m_behavior = " << m_behavior << std::endl;
422 // std::cerr << "[DEBUG]: rsync_behavior::ok = " << rsync_behavior::ok << std::endl;
423  if (
424  /*
425  ((m_exit_code == 0) && (m_signal_num == 0))
426  || (m_behavior == rsync_behavior::ok)
427  */
428  ((m_exit_code == 0) || (m_behavior == rsync_behavior::ok))
429  && (m_signal_num == 0)
430  ) {
431 // std::cerr << "[DEBUG]: job_path_report::status() = true" << std::endl;
432  return(true);
433  }
434 // std::cerr << "[DEBUG]: job_path_report::status() = false" << std::endl;
435  return(false);
436 }
437 
438 /** Set the path archived for this report */
439 void job_path_report::source(const std::string& a_class)
440 {
441  TRY_nomem(m_source = a_class);
442 }
443 
444 /** Return a string of the path archived */
445 const std::string& job_path_report::source(void) const
446 {
447  return(m_source);
448 }
449 
450 /** Set the timer values for this report */
451 void job_path_report::time(const timer& a_class)
452 {
453  TRY_nomem(m_time = a_class);
454 }
455 
456 /** Return the timer object for this report */
457 const timer& job_path_report::time(void) const
458 {
459  return(m_time);
460 }
461 
462 /** Set rsync's return exit code when archiving this path */
463 void job_path_report::exit_code(const int a_exit_code)
464 {
465  m_exit_code = a_exit_code;
466 }
467 
468 /** Return rsync's exit code */
469 const int job_path_report::exit_code(void) const
470 {
471  return(m_exit_code);
472 }
473 
474 /** Set rsync's signal number from archiving this path */
475 void job_path_report::signal_num(const int a_signal_num)
476 {
477  m_signal_num = a_signal_num;
478 }
479 
480 /** Return rsync's signal number */
481 const int job_path_report::signal_num(void) const
482 {
483  return(m_signal_num);
484 }
485 
486 /** Set a descriptive error message for this report */
487 void job_path_report::error_msg(const std::string& a_class)
488 {
489  TRY_nomem(m_error_msg = a_class);
490 }
491 
492 /** Return the error message */
493 const std::string& job_path_report::error_msg(void) const
494 {
495  return(m_error_msg);
496 }
497 
498 /** Assignment operator */
500 {
501  assign(a_class);
502  return(*this);
503 }
504 
505 //-----------------------------------------------------------------------------
506 
507 /** Report type tags */
508 const char *reportio::tags[] = {
509  "[RSYNC]: ",
510  "[REPORT]: ",
511  0
512 };
513 
514 /** Write a report line for output from rsync to parent on child's std::cout
515  */
516 void reportio::write_rsync_out(const std::string& a_str)
517 {
518  std::cout.flush();
519  std::cout << tags[rsync] << a_str << std::endl;
520  std::cout.flush();
521 }
522 
523 /** Write a report line for output from rsync to parent on child's std::cerr
524  */
525 void reportio::write_rsync_err(const std::string& a_str)
526 {
527  std::cerr.flush();
528  std::cerr << tags[rsync] << a_str << std::endl;
529  std::cerr.flush();
530 }
531 
532 /** Generate and submit a report to the parent process on child's std::cout
533  */
535  const std::string a_source,
536  const timer& a_timer,
537  const int a_exit_code,
538  const int a_signal_num,
539  const rsync_behavior::value_type& a_behavior,
540  const std::string& a_error_msg
541  )
542 {
543  estring str;
544 
545  str += estring(a_source.size());
546  str += " ";
547  str += a_source;
548  str += " ";
549  str += estring(static_cast<uint64>(a_timer.start_value()));
550  str += " ";
551  str += estring(static_cast<uint64>(a_timer.stop_value()));
552  str += " ";
553  str += estring(a_exit_code);
554  str += " ";
555  str += estring(a_signal_num);
556  str += " ";
557  str += estring(static_cast<uint64>(a_behavior));
558  str += " ";
559  str += estring(a_error_msg.size());
560  str += " ";
561  str += a_error_msg;
562  str += " ";
563 
564  std::cout.flush();
565  std::cout << tags[report] << str << std::endl;
566  std::cout.flush();
567 }
568 
569 /** Parse a received report from a child process and return a job_path_report
570  */
571 job_path_report reportio::parse(const std::string& a_str)
572 {
573  estring es;
574  job_path_report jpr;
575  estring estr;
576  estring::size_type idx;
577  estring::size_type size;
578  estring tmp;
579  estring source;
580  timer::value_type start_time;
581  timer::value_type stop_time;
582  int exit_code;
583  int signal_num;
584  estring error_msg;
586 
587  TRY_nomem(estr = a_str);
588  idx = estr.find(tags[report]);
589  if (idx == std::string::npos) {
590  estring es;
591 
592  es = "Invalid job report: \"";
593  es += a_str;
594  es += "\"";
595 
596  throw(INTERNAL_ERROR(0,es));
597  }
598 
599  // TODO: A lot of assumptions are being made here, put in some checking code
600 
601  estr.erase(0,idx+strlen(tags[report]));
602 
603  idx = estr.find(' ');
604  tmp = estr.substr(0,idx);
605  estr.erase(0,idx+1);
606  size = tmp;
607  source = estr.substr(0,size);
608  estr.erase(0,size+1);
609 
610  idx = estr.find(' ');
611  tmp = estr.substr(0,idx);
612  estr.erase(0,idx+1);
613  start_time = static_cast<uint64>(tmp);
614 
615  idx = estr.find(' ');
616  tmp = estr.substr(0,idx);
617  estr.erase(0,idx+1);
618  stop_time = static_cast<uint64>(tmp);
619 
620  idx = estr.find(' ');
621  tmp = estr.substr(0,idx);
622  estr.erase(0,idx+1);
623  exit_code = tmp;
624 
625  idx = estr.find(' ');
626  tmp = estr.substr(0,idx);
627  estr.erase(0,idx+1);
628  signal_num = tmp;
629 
630  idx = estr.find(' ');
631  tmp = estr.substr(0,idx);
632  estr.erase(0,idx+1);
633  behavior =
634  static_cast<rsync_behavior::value_type>(
635  static_cast<uint64>(tmp)
636  );
637 
638  idx = estr.find(' ');
639  tmp = estr.substr(0,idx);
640  estr.erase(0,idx+1);
641  size = tmp;
642  error_msg = estr.substr(0,size);
643  estr.erase(0,size+1);
644 
645  jpr.assign(
646  source,
647  timer(start_time,stop_time),
648  exit_code,
649  signal_num,
650  behavior,
651  error_msg
652  );
653 
654  return(jpr);
655 }
656 
657 /** Return true if the given string looks like a valid report */
658 bool reportio::is_report(const std::string& a_class)
659 {
660  estring::size_type idx;
661 
662  idx = a_class.find(tags[report]);
663  if (idx == std::string::npos) {
664  return(false);
665  }
666  return(true);
667 }
668 
669 //-----------------------------------------------------------------------------
670 
671 /** C'tor */
673 {
674  clear();
675 }
676 
677 /** D'tor */
679 {
680 }
681 
682 /** Clear all values */
684 {
685  m_reports.clear();
686  m_id.erase();
687 }
688 
689 /** Add a path report for this job */
691 {
692  TRY_nomem(m_reports.push_back(a_class));
693 }
694 
695 /** Return a const vector of all path reports */
696 const std::vector<job_path_report>& single_job_report::reports(void) const
697 {
698  return(m_reports);
699 }
700 
701 /** Set a descriptive ID for this job report */
702 void single_job_report::id(const std::string& a_str)
703 {
704  TRY_nomem(m_id = a_str);
705 }
706 
707 /** Return the descriptive id for this job report */
708 const std::string& single_job_report::id(void) const
709 {
710  return(m_id);
711 }
712 
713 /** If all path reports say that rsync was successful, then return true, else
714  * return false */
715 const bool single_job_report::status(void) const
716 {
717  bool value = true;
718  std::vector<job_path_report>::const_iterator jpri;
719 
720  for (jpri = m_reports.begin(); jpri != m_reports.end(); ++jpri) {
721  if (!jpri->status())
722  value = false;
723  }
724 
725  return(value);
726 }
727 
728 //-----------------------------------------------------------------------------
729 
730 /** C'tor */
732 {
733  clear();
734 }
735 
736 /** D'tor */
738 {
739 }
740 
741 /** Clear all values */
743 {
744  m_jobs.clear();
745 }
746 
747 /** Add a job report to the list */
749 {
750  TRY_nomem(m_jobs.push_back(a_class));
751 }
752 
753 /** Return a const vector of all job reports */
754 const std::vector<single_job_report>& jobs_report::reports(void) const
755 {
756  return(m_jobs);
757 }
758 
759 /** Format job reports and output to the given stream */
760 void jobs_report::write_report(std::ostream& a_out)
761 {
762  std::vector<single_job_report>::const_iterator ji;
763  std::vector<job_path_report>::const_iterator jpi;
764  estring estr;
765  estring estr2;
766  estring hsep;
767  estring vsep;
768  estring vsep2;
769 
770  hsep.fillchar('-');
771  vsep = " | ";
772  vsep2 = "|";
773 
774  for (ji = m_jobs.begin(); ji != m_jobs.end(); ++ji) {
775  table t1, t2;
776  bool first_line = true;
777 
778  if (ji != m_jobs.begin())
779  a_out << std::endl;
780 
781  estr.align(estring::left);
782  estr = "Job: ";
783  estr += ji->id();
784  t1 << estr;
785  t1 << table_endl;
786 
787  t1 << hsep;
788  t1 << table_endl;
789 
790  t2 << "Job" << vsep << "Path" << " " << " "
791  << table_endl;
792  t2 << "Status" << vsep << "Status" << " " << "Source"
793  << table_endl;
794  t2 << hsep << vsep << hsep << " " << hsep << table_endl;
795 
796  for (jpi = ji->reports().begin(); jpi != ji->reports().end(); ++jpi) {
797  if (jpi != ji->reports().begin())
798  t2 << table_endl;
799 
800  if (first_line) {
801  if (ji->status())
802  t2 << "OK";
803  else
804  t2 << "ERROR";
805  first_line = false;
806  }
807  else {
808  t2 << " " << vsep << " " << " " << table_endl << " ";
809  }
810 
811  t2 << table_repeat << vsep;
812 
813  if (jpi->status())
814  t2 << "OK";
815  else
816  t2 << "ERROR";
817 
818  t2 << " ";
819 
820  t2 << jpi->source();
821 
822  t2 << table_endl;
823 
824  t2 << " " << table_repeat << vsep << " " << " ";
825 
826  table t3, t4;
827 
828  t3 << "+" << hsep << hsep << table_endl;
829  t3 << table_repeat << vsep2 << " ";
830 
831  estr.align(estring::right);
832  estr2.align(estring::right);
833 
834  estr = "Start:";
835  estr2 = jpi->time().started_at();
836  estr2 += " ";
837  t4 << " " << estr << " " << estr2 << table_endl;
838 
839  estr = "Finish:";
840  estr2 = jpi->time().stopped_at();
841  estr2 += " ";
842  t4 << " " << estr << " " << estr2 << table_endl;
843 
844  estr = "Duration:";
845  estr2 = jpi->time().duration();
846  t4 << " " << estr << " " << estr2 << table_endl;
847 
848  t3 << t4 << table_endl;
849 
850  estr2.align(estring::left);
851  if (!jpi->status()) {
852  table t5;
853 
854  t3 << vsep2 << " " << " " << table_endl;
855  t3 << table_repeat << vsep2 << " ";
856 
857  estr = "Exit Code:";
858  estr2 = estring(jpi->exit_code());
859  if (jpi->exit_code() != 0) {
860  estr2 += " ";
861  estr2 += rsync_estat_str.exit(jpi->exit_code());
862  }
863  t5 << " " << estr << " " << estr2 << table_endl;
864 
865  estr = "Signal Num:";
866  estr2 = estring(jpi->signal_num());
867  if (jpi->signal_num() != 0) {
868  estr2 += " ";
869  estr2 += rsync_estat_str.signal(jpi->signal_num());
870  }
871  t5 << " " << estr << " " << estr2 << table_endl;
872 
873  if (jpi->error_msg().size() > 0) {
874  estr = "Error Msg:";
875  estr2 = jpi->error_msg();
876  t5 << " " << estr << " " << estr2 << table_endl;
877  }
878 
879  t3 << t5;
880  }
881 
882  // TODO: File statistics should go here
883 
884  t2 << t3;
885  }
886 
887  t1 << t2;
888 
889  a_out << t1;
890  }
891 }
892 
893 /** Generate a synopsis report */
895 {
896  estring estr, estr2;
897  std::vector<single_job_report>::const_iterator sjri;
898  uint16 jobs_good = 0;
899  uint16 jobs_bad = 0;
900  uint16 jobs_total = 0;
901 
902  estr.align(estring::right);
903 
904  for (sjri = m_jobs.begin(); sjri != m_jobs.end(); ++sjri) {
905  if (sjri->status())
906  ++jobs_good;
907  else
908  ++jobs_bad;
909  ++jobs_total;
910  }
911 
912  estr = "Successful Jobs:";
913  estr2 = estring(jobs_good);
914  estr2 += " out of ";
915  estr2 += estring(m_jobs.size());
916  estr2 += " (";
917  estr2 += percent_string(jobs_good, jobs_total);
918  estr2 += ")";
919 
920  a_table << estr << " " << estr2 << table_endl;
921 }
922 
923 //-----------------------------------------------------------------------------
924 
925 /** C'tor */
927 {
928  m_initialized = false;
929 }
930 
931 /** D'tor */
933 {
934 }
935 
936 /** Initialize */
938 {
939  if (!config.initialized()) {
940  throw(INTERNAL_ERROR(0,"Configuration manager is not initialized"));
941  }
942  m_initialized = true;
943 }
944 
945 /** Return whether or not this object has been inintialized */
946 const bool report_manager::initialized(void) const
947 {
948  return(m_initialized);
949 }
950 
951 /** Clear all values */
953 {
955  m_vault.clear();
956  m_jobs.clear();
957 }
958 
959 /** Report the overall RVM time */
961 {
962  if (!initialized())
963  throw(INTERNAL_ERROR(0,"Report manager is not initialized"));
964 
965  m_total_time = a_class;
966 }
967 
968 /** Return the vault reporter object */
970 {
971  return(m_vault);
972 }
973 
974 /** Return the jobs reporter object */
976 {
977  return(m_jobs);
978 }
979 
980 /** Print report to standard output */
982 {
983  estring lstr;
984 
985  if (!initialized())
986  throw(INTERNAL_ERROR(0,"Report manager is not initialized"));
987 
988  lstr = "Reporter - Printing report to stdout...\n";
989  logger.write(lstr);
990 
991  write_report(std::cout);
992 
993  lstr = "Reporter - Done\n";
994  logger.write(lstr);
995 }
996 
997 /** Save report to a file */
999 {
1000  std::ofstream out;
1001  std::string filename;
1002  std::string es;
1003  estring lstr;
1004  bool done = false;
1005  int count = 0;
1006 
1007  if (!initialized())
1008  throw(INTERNAL_ERROR(0,"Report manager is not initialized"));
1009 
1010  while (!done) {
1011  TRY_nomem(filename = config.log_dir());
1012  TRY_nomem(filename += "/");
1013  TRY_nomem(filename += config.timestamp().str());
1014  TRY_nomem(filename += ".report");
1015  if (count != 0) {
1016  TRY_nomem(filename += ".");
1017  TRY_nomem(filename += estring(count));
1018  }
1019  if (exists(filename))
1020  ++count;
1021  else
1022  done = true;
1023  }
1024  out.open(filename.c_str());
1025  if (!out.is_open()) {
1026  TRY_nomem(es = "Could not open report file: \"");
1027  TRY_nomem(es += filename);
1028  TRY_nomem(es += "\"");
1029  throw(ERROR(errno,es));
1030  }
1031 
1032  lstr = "Reporter - Writing report to file...\n";
1033  logger.write(lstr);
1034  write_report(out);
1035 
1036  out.close();
1037 
1038  lstr = "Reporter - Done\n";
1039  logger.write(lstr);
1040 }
1041 
1042 /** Write report to the given stream */
1043 void report_manager::write_report(std::ostream& a_out)
1044 {
1045  estring estr;
1046  estring es;
1047 
1048  mf_write_header(a_out);
1049 
1050  a_out << std::endl;
1051 
1052  mf_write_synopsis(a_out);
1053 
1054  a_out << std::endl;
1055 
1056  m_jobs.write_report(a_out);
1057 
1058  a_out << std::endl;
1059 
1060  m_vault.write_report(a_out);
1061 
1062  a_out << std::endl;
1063 }
1064 
1065 /** Generate a synopsis report */
1067 {
1068  estring estr;
1069  estring estr2;
1070 
1071  estr.align(estring::right);
1072  estr2.align(estring::right);
1073 
1074  estr = "Start Time:";
1075  estr2 = m_total_time.started_at();
1076  estr2 += " ";
1077 
1078  a_table << estr << " " << estr2 << table_endl;
1079 
1080  estr = "Finish Time:";
1081  estr2 = m_total_time.stopped_at();
1082  estr2 += " ";
1083 
1084  a_table << estr << " " << estr2 << table_endl;
1085 
1086  estr = "Duration:";
1087  estr2 = m_total_time.duration();
1088 
1089  a_table << estr << " " << estr2 << table_endl;
1090 }
1091 
1092 void report_manager::mf_write_header(std::ostream& a_out)
1093 {
1094  table t;
1095  estring estr;
1096 
1097  estr = "Rsync Vault Manager - ";
1098  estr += VERSION;
1099 
1100  t << estr << table_endl;
1101 
1102  estr = "";
1103  estr.fillchar('=');
1104  t << estr;
1105 
1106  a_out << t;
1107 }
1108 
1109 void report_manager::mf_write_synopsis(std::ostream& a_out)
1110 {
1111  table t;
1112  estring estr;
1113 
1114  format_synopsis(t);
1115  vault().format_synopsis(t);
1116  jobs().format_synopsis(t);
1117 
1118  a_out << t;
1119 }
1120 
1121 //-----------------------------------------------------------------------------
1122 
1123 /** The global report manager */
1125 
single_job_report()
C'tor.
Definition: reporter.cc:672
Left-justified.
Definition: estring.h:64
Retrieve information about a filesystem.
Definition: fs.h:316
const size_type total_inodes(void) const
Return the filesystem's total number of inodes, if supported by the filesystem, otherwise the result ...
Definition: fs.cc:1662
log_manager logger
The global log manager.
Definition: logger.cc:138
job_path_report parse(const std::string &a_str)
Parse a received report from a child process and return a job_path_report.
Definition: reporter.cc:571
uint64 m_free_blocks
Definition: reporter.h:62
Vault selection and usage report.
Definition: reporter.h:68
void clear(void)
Clear all values.
Definition: reporter.cc:683
table & table_endl(table &a_table)
Definition: table.cc:853
const uint64 free_inodes(void) const
Return the number of free inodes in the vault.
Definition: reporter.cc:143
const std::string & error_msg(void) const
Return the error message.
Definition: reporter.cc:493
void write_report(std::ostream &a_out)
Format job reports and output to the given stream.
Definition: reporter.cc:760
An extended string class.
Definition: estring.h:52
void add_report(const single_job_report &a_class)
Add a job report to the list.
Definition: reporter.cc:748
#define ASSERT(code)
Definition: asserts.h:9
std::vector< vault_stats_report > m_reports
Definition: reporter.h:82
report_manager()
C'tor.
Definition: reporter.cc:926
job_path_report & operator=(const job_path_report &a_class)
Assignment operator.
Definition: reporter.cc:499
void format_synopsis(table &a_table)
Generate a synopsis report.
Definition: reporter.cc:318
vault_stats_report()
C'tor.
Definition: reporter.cc:26
const std::string current_time(void)
Return the current time.
Definition: timer.cc:542
Right-justified.
Definition: estring.h:66
#define VERSION
Definition: config.h:214
A single job report.
Definition: reporter.h:164
void write_rsync_err(const std::string &a_str)
Write a report line for output from rsync to parent on child's std::cerr.
Definition: reporter.cc:525
jobs_report m_jobs
Definition: reporter.h:235
void mf_write_synopsis(std::ostream &a_out)
Definition: reporter.cc:1109
std::string percent_string(const T &a_complete, const T &a_total)
Given a count complete and a count total, calculate a percentage.
Definition: strfmt.h:157
void write_report(std::ostream &a_out)
Write report to the given stream.
Definition: reporter.cc:1043
~vault_report()
D'tor.
Definition: reporter.cc:165
const std::vector< single_job_report > & reports(void) const
Return a const vector of all job reports.
Definition: reporter.cc:754
void clear(void)
Clear the timer.
Definition: timer.cc:98
void write(const std::string &a_str, const uint16 a_indention=0, const configuration_manager::logging_type a_logging_level=configuration_manager::logging_manager, const pid_t a_pid=pid())
Write a string to the log file.
Definition: logger.cc:96
const uint64 total_blocks(void) const
Return the total number of blocks in the vault.
Definition: reporter.cc:125
const class timestamp & timestamp(void) const
Return the timestamp of this instance of rvm.
Definition: rconfig.cc:1505
const std::string & log_dir(void) const
Return the log-dir path.
Definition: rconfig.cc:1523
class rstat rsync_estat_str
Definition: archiver.cc:114
const std::vector< job_path_report > & reports(void) const
Return a const vector of all path reports.
Definition: reporter.cc:696
void write_report(std::ostream &a_out)
Format and print the vault report to the given stream.
Definition: reporter.cc:184
uint64 m_free_inodes
Definition: reporter.h:64
jobs_report()
C'tor.
Definition: reporter.cc:731
void set_total_time(const timer &a_class)
Report the overall RVM time.
Definition: reporter.cc:960
rsync_behavior::value_type m_behavior
Definition: reporter.h:134
std::string m_time
Definition: reporter.h:59
table & table_repeat(table &a_table)
Definition: table.cc:883
const bool status(void) const
Return true if rsync succeeded archiving this path.
Definition: reporter.cc:414
Centered.
Definition: estring.h:68
Vault stats report.
Definition: reporter.h:13
void clear(void)
Clear all values.
Definition: reporter.cc:952
void clear(void)
Clear all values.
Definition: reporter.cc:54
report_manager reporter
The global report manager.
Definition: reporter.cc:1124
jobs_report & jobs(void)
Return the jobs reporter object.
Definition: reporter.cc:975
const std::string & exit(const int a_int) const
Get a verbose string for an exit code.
Definition: archiver.cc:97
uint64 m_total_inodes
Definition: reporter.h:63
bool exists(const std::string &a_path)
Return true if the file or directory exists.
Definition: fs.cc:385
void file_report(void)
Save report to a file.
Definition: reporter.cc:998
timer m_total_time
Definition: reporter.h:233
#define TRY_nomem(code)
Definition: error.h:144
const std::string & message(void) const
Return the message.
Definition: reporter.cc:119
vault_report m_vault
Definition: reporter.h:234
All job reports.
Definition: reporter.h:186
const std::string stopped_at(void) const
Generate a stopped-at string.
Definition: timer.cc:371
const value_type start_value(void) const
Return the timer start value.
Definition: timer.cc:150
~vault_stats_report()
D'tor.
Definition: reporter.cc:49
const bool initialized(void) const
Return the initialized state of the configuration manager.
Definition: rconfig.cc:1459
void fillchar(const char a_char)
Set the fill character used for padding both the left and right side of a formatted string...
Definition: estring.cc:662
const std::string vault(void) const
Return the path to the selected vault.
Definition: vaulter.cc:291
vault_stats_report & operator=(const vault_stats_report &a_class)
Assignment operator.
Definition: reporter.cc:150
void add_report(const job_path_report &a_class)
Add a path report for this job.
Definition: reporter.cc:690
~jobs_report()
D'tor.
Definition: reporter.cc:737
const std::string & source(void) const
Return a string of the path archived.
Definition: reporter.cc:445
void clear(void)
Clear all values.
Definition: reporter.cc:372
const size_type free_inodes(void) const
Return the filesystem's total number of free inodes, if supported by the filesystem, otherwise the result is system-dependent, but usually 0.
Definition: fs.cc:1674
void assign(const vault_stats_report &a_class)
Assignment.
Definition: reporter.cc:63
~single_job_report()
D'tor.
Definition: reporter.cc:678
const std::string & signal(const int a_int) const
Get a verbose string for a signal number.
Definition: archiver.cc:106
#define INTERNAL_ERROR(e, s)
Definition: error.h:123
const std::string & time(void) const
Return a string timestamp.
Definition: reporter.cc:113
Job report for an rsync run on a single path.
Definition: reporter.h:86
const std::string started_at(void) const
Generate a started-at string.
Definition: timer.cc:359
configuration_manager config
The global configuration manager instance.
Definition: rconfig.cc:3364
const std::string & id(void) const
Return the descriptive id for this job report.
Definition: reporter.cc:708
void format_synopsis(table &a_table)
Generate a synopsis report.
Definition: reporter.cc:1066
static const char * tags[]
Report type tags.
Definition: reporter.h:145
time_t value_type
Definition: timer.h:32
std::string m_source
Definition: reporter.h:129
job_path_report()
C'tor.
Definition: reporter.cc:333
std::vector< job_path_report > m_reports
Definition: reporter.h:181
vault_report & vault(void)
Return the vault reporter object.
Definition: reporter.cc:969
const value_type stop_value(void) const
Return the timer stop value.
Definition: timer.cc:156
The report manager.
Definition: reporter.h:210
void write_report(const std::string a_source, const timer &a_timer, const int a_exit_code, const int a_signal_num, const rsync_behavior::value_type &a_behavior, const std::string &a_error_msg)
Generate and submit a report to the parent process on child's std::cout.
Definition: reporter.cc:534
value_type::size_type size_type
The size type.
Definition: estring.h:59
void print_report(void)
Print report to standard output.
Definition: reporter.cc:981
vault_report()
C'tor.
Definition: reporter.cc:159
void format_synopsis(table &a_table)
Generate a synopsis report.
Definition: reporter.cc:894
void clear(void)
Clear all values.
Definition: reporter.cc:170
const size_type free_blocks(void) const
Return the filesystem's number of free blocks.
Definition: fs.cc:1640
const std::string duration(void) const
Generate a duration string.
Definition: timer.cc:385
const uint64 total_inodes(void) const
Return the total number of inodes in the vault.
Definition: reporter.cc:137
void assign(const job_path_report &a_class)
Assignment.
Definition: reporter.cc:383
~report_manager()
D'tor.
Definition: reporter.cc:932
void add_report(const vault_stats_report &a_class)
Add a vault report to the list.
Definition: reporter.cc:176
const timer & time(void) const
Return the timer object for this report.
Definition: reporter.cc:457
alignment align(const alignment a_alignment)
Set the alignment used for formatted strings.
Definition: estring.cc:471
const int signal_num(void) const
Return rsync's signal number.
Definition: reporter.cc:481
std::vector< single_job_report > m_jobs
Definition: reporter.h:202
std::string m_error_msg
Definition: reporter.h:133
void mf_write_header(std::ostream &a_out)
Definition: reporter.cc:1092
void clear(void)
Clear all values.
Definition: reporter.cc:742
bool is_report(const std::string &a_str)
Return true if the given string looks like a valid report.
Definition: reporter.cc:658
const uint64 free_blocks(void) const
Return the number of free blocks in the vault.
Definition: reporter.cc:131
const std::string str(void) const
Generate a string.
Definition: tstamp.cc:387
#define ERROR(e, s)
Definition: error.h:120
bool m_initialized
Definition: reporter.h:232
std::string m_message
Definition: reporter.h:60
~job_path_report()
D'tor.
Definition: reporter.cc:367
void init(void)
Initialize.
Definition: reporter.cc:937
uint64 m_total_blocks
Definition: reporter.h:61
void write_rsync_out(const std::string &a_str)
Write a report line for output from rsync to parent on child's std::cout.
Definition: reporter.cc:516
const size_type total_blocks(void) const
Return the filesystem's total number of blocks.
Definition: fs.cc:1630
Definition: table.h:96
const bool initialized(void) const
Return whether or not this object has been inintialized.
Definition: reporter.cc:946
Used as a stopwatch.
Definition: timer.h:29
std::string m_id
Definition: reporter.h:182
vault_manager vaulter
The global vault manager.
Definition: vaulter.cc:772
const bool status(void) const
If all path reports say that rsync was successful, then return true, else return false.
Definition: reporter.cc:715
const int exit_code(void) const
Return rsync's exit code.
Definition: reporter.cc:469