00001 #include "config.h"
00002
00003 #include <iostream>
00004 #include <string>
00005 #include <vector>
00006 #include <algorithm>
00007
00008 #include "asserts.h"
00009 #include "error.h"
00010 #include "estring.h"
00011 #include "fs.h"
00012 #include "rconfig.h"
00013 #include "timer.h"
00014 #include "logger.h"
00015 #include "estat.h"
00016 #include "vaulter.h"
00017 #include "strfmt.h"
00018 #include "archiver.h"
00019 #include "table.h"
00020
00021 #include "reporter.h"
00022
00023
00024
00025
00026 vault_stats_report::vault_stats_report()
00027 {
00028 clear();
00029 }
00030
00031
00032 vault_stats_report::vault_stats_report(const vault_stats_report& a_class)
00033 {
00034 clear();
00035 assign(a_class);
00036 }
00037
00038
00039 vault_stats_report::vault_stats_report(
00040 const std::string& a_message,
00041 const filesystem& a_class
00042 )
00043 {
00044 clear();
00045 assign(a_message,a_class);
00046 }
00047
00048
00049 vault_stats_report::~vault_stats_report()
00050 {
00051 }
00052
00053
00054 void vault_stats_report::clear(void)
00055 {
00056 m_total_blocks = 0;
00057 m_free_blocks = 0;
00058 m_total_inodes = 0;
00059 m_free_inodes = 0;
00060 }
00061
00062
00063 void vault_stats_report::assign(
00064 const vault_stats_report& a_class
00065 )
00066 {
00067 assign(
00068 a_class.message(),
00069 a_class.time(),
00070 a_class.total_blocks(),
00071 a_class.free_blocks(),
00072 a_class.total_inodes(),
00073 a_class.free_inodes()
00074 );
00075 }
00076
00077
00078 void vault_stats_report::assign(
00079 const std::string& a_message,
00080 const filesystem& a_class
00081 )
00082 {
00083 assign(
00084 a_message,
00085 current_time(),
00086 a_class.total_blocks(),
00087 a_class.free_blocks(),
00088 a_class.total_inodes(),
00089 a_class.free_inodes()
00090 );
00091 }
00092
00093
00094 void vault_stats_report::assign(
00095 const std::string& a_message,
00096 const std::string& a_time,
00097 const uint64 a_total_blocks,
00098 const uint64 a_free_blocks,
00099 const uint64 a_total_inodes,
00100 const uint64 a_free_inodes
00101 )
00102 {
00103 TRY_nomem(m_message = a_message);
00104 m_total_blocks = a_total_blocks;
00105 m_free_blocks = a_free_blocks;
00106 m_total_inodes = a_total_inodes;
00107 m_free_inodes = a_free_inodes;
00108
00109 TRY_nomem(m_time = a_time);
00110 }
00111
00112
00113 const std::string& vault_stats_report::time(void) const
00114 {
00115 return(m_time);
00116 }
00117
00118
00119 const std::string& vault_stats_report::message(void) const
00120 {
00121 return(m_message);
00122 }
00123
00124
00125 const uint64 vault_stats_report::total_blocks(void) const
00126 {
00127 return(m_total_blocks);
00128 }
00129
00130
00131 const uint64 vault_stats_report::free_blocks(void) const
00132 {
00133 return(m_free_blocks);
00134 }
00135
00136
00137 const uint64 vault_stats_report::total_inodes(void) const
00138 {
00139 return(m_total_inodes);
00140 }
00141
00142
00143 const uint64 vault_stats_report::free_inodes(void) const
00144 {
00145 return(m_free_inodes);
00146 }
00147
00148
00149 vault_stats_report&
00150 vault_stats_report::operator=(const vault_stats_report& a_class)
00151 {
00152 assign(a_class);
00153 return(*this);
00154 }
00155
00156
00157
00158
00159 vault_report::vault_report()
00160 {
00161 clear();
00162 }
00163
00164
00165 vault_report::~vault_report()
00166 {
00167 }
00168
00169
00170 void vault_report::clear(void)
00171 {
00172 m_reports.clear();
00173 }
00174
00175
00176 void vault_report::add_report(
00177 const vault_stats_report& a_class
00178 )
00179 {
00180 TRY_nomem(m_reports.push_back(a_class));
00181 }
00182
00183
00184 void vault_report::write_report(std::ostream& out)
00185 {
00186 table tab, tab2;
00187 estring estr;
00188 std::vector<vault_stats_report>::const_iterator vi;
00189 uint64 ui64b, ui64e, ui64t;
00190
00191 estr = "Vault Statistics";
00192 estr.align(estring::center);
00193 tab << estr << table_endl;
00194
00195 estr = "";
00196 estr.fillchar('-');
00197 estr.align(estring::left);
00198 tab << estr << table_endl;
00199
00200
00201 tab2
00202 << "Time"
00203 << " "
00204 << "Message"
00205 << " "
00206 << "Free Blocks"
00207 << " "
00208 << "Free Inodes"
00209 << " "
00210 << table_endl;
00211
00212
00213 estr.align(estring::left);
00214 estr.fillchar('-');
00215 estr = "";
00216 tab2
00217 << estr
00218 << " "
00219 << estr
00220 << " "
00221 << estr
00222 << " "
00223 << estr
00224 << table_endl;
00225
00226
00227 estr.fillchar(' ');
00228 for (vi = m_reports.begin(); vi != m_reports.end(); ++vi) {
00229 tab2
00230 << vi->time()
00231 << " ";
00232
00233 estr.align(estring::right);
00234 estr = vi->message();
00235 tab2 << estr;
00236
00237 tab2 << " ";
00238
00239 estr.align(estring::center);
00240
00241 estr = " ";
00242 estr += percent_string(vi->free_blocks(), vi->total_blocks());
00243 tab2 << estr;
00244
00245 tab2 << " ";
00246
00247 estr = " ";
00248 estr += percent_string(vi->free_inodes(), vi->total_inodes());
00249 tab2 << estr;
00250
00251 tab2 << table_endl;
00252 }
00253
00254
00255 estr.align(estring::left);
00256 estr.fillchar('-');
00257 estr = "";
00258 tab2
00259 << " "
00260 << " "
00261 << " "
00262 << " "
00263 << estr
00264 << " "
00265 << estr
00266 << table_endl;
00267
00268
00269 estr.align(estring::right);
00270 estr.fillchar(' ');
00271 estr = "Total Difference:";
00272
00273
00274 tab2
00275 << " "
00276 << " "
00277 << estr
00278 << " ";
00279
00280 estr.align(estring::center);
00281 ASSERT(m_reports.size() > 0);
00282 ui64b = m_reports[0].free_blocks();
00283 ui64e = m_reports[m_reports.size()-1].free_blocks();
00284 ui64t = m_reports[0].total_blocks();
00285 if (ui64b > ui64e) {
00286 estr = "-";
00287 estr += percent_string(ui64b - ui64e, ui64t);
00288 }
00289 else {
00290 estr = "+";
00291 estr += percent_string(ui64e - ui64b, ui64t);
00292 }
00293 tab2 << estr;
00294
00295 tab2 << " ";
00296
00297 ui64b = m_reports[0].free_inodes();
00298 ui64e = m_reports[m_reports.size()-1].free_inodes();
00299 ui64t = m_reports[0].total_inodes();
00300 if (ui64b > ui64e) {
00301 estr = "-";
00302 estr += percent_string(ui64b - ui64e, ui64t);
00303 }
00304 else {
00305 estr = "+";
00306 estr += percent_string(ui64e - ui64b, ui64t);
00307 }
00308 tab2 << estr;
00309
00310 tab2 << table_endl;
00311
00312 tab << tab2;
00313
00314 out << tab;
00315 }
00316
00317
00318 void vault_report::format_synopsis(table& a_table)
00319 {
00320 estring estr;
00321
00322 estr.align(estring::right);
00323 estr = "Timestamp:";
00324 a_table << estr << " " << config.timestamp().str() << table_endl;
00325
00326 estr = "Vault Selected:";
00327 a_table << estr << " " << vaulter.vault() << table_endl;
00328 }
00329
00330
00331
00332
00333 job_path_report::job_path_report()
00334 {
00335 clear();
00336 }
00337
00338
00339 job_path_report::job_path_report(const job_path_report& a_class)
00340 {
00341 clear();
00342 assign(a_class);
00343 }
00344
00345
00346 job_path_report::job_path_report(
00347 const std::string a_source,
00348 const timer a_time,
00349 const uint16 a_exit_code,
00350 const uint16 a_signal_num,
00351 const std::string a_error_message
00352 )
00353 {
00354 clear();
00355 assign(a_source, a_time, a_exit_code, a_signal_num, a_error_message);
00356 }
00357
00358
00359 job_path_report::~job_path_report()
00360 {
00361 }
00362
00363
00364 void job_path_report::clear(void)
00365 {
00366 m_source.erase();
00367 m_time.clear();
00368 m_exit_code = 0;
00369 m_signal_num = 0;
00370 m_error_msg.erase();
00371 }
00372
00373
00374 void job_path_report::assign(const job_path_report& a_class)
00375 {
00376 assign(
00377 a_class.m_source,
00378 a_class.m_time,
00379 a_class.m_exit_code,
00380 a_class.m_signal_num,
00381 a_class.m_error_msg
00382 );
00383 }
00384
00385
00386 void job_path_report::assign(
00387 const std::string a_source,
00388 const timer a_time,
00389 const uint16 a_exit_code,
00390 const uint16 a_signal_num,
00391 const std::string a_error_message
00392 )
00393 {
00394 TRY_nomem(m_source = a_source);
00395 TRY_nomem(m_error_msg = a_error_message);
00396 TRY_nomem(m_time = a_time);
00397 m_exit_code = a_exit_code;
00398 m_signal_num = a_signal_num;
00399 }
00400
00401
00402 const bool job_path_report::status(void) const
00403 {
00404 if ((m_exit_code == 0) && (m_signal_num == 0)) {
00405 return(true);
00406 }
00407 return(false);
00408 }
00409
00410
00411 void job_path_report::source(const std::string& a_class)
00412 {
00413 TRY_nomem(m_source = a_class);
00414 }
00415
00416
00417 const std::string& job_path_report::source(void) const
00418 {
00419 return(m_source);
00420 }
00421
00422
00423 void job_path_report::time(const timer& a_class)
00424 {
00425 TRY_nomem(m_time = a_class);
00426 }
00427
00428
00429 const timer& job_path_report::time(void) const
00430 {
00431 return(m_time);
00432 }
00433
00434
00435 void job_path_report::exit_code(const int a_exit_code)
00436 {
00437 m_exit_code = a_exit_code;
00438 }
00439
00440
00441 const int job_path_report::exit_code(void) const
00442 {
00443 return(m_exit_code);
00444 }
00445
00446
00447 void job_path_report::signal_num(const int a_signal_num)
00448 {
00449 m_signal_num = a_signal_num;
00450 }
00451
00452
00453 const int job_path_report::signal_num(void) const
00454 {
00455 return(m_signal_num);
00456 }
00457
00458
00459 void job_path_report::error_msg(const std::string& a_class)
00460 {
00461 TRY_nomem(m_error_msg = a_class);
00462 }
00463
00464
00465 const std::string& job_path_report::error_msg(void) const
00466 {
00467 return(m_error_msg);
00468 }
00469
00470
00471 job_path_report& job_path_report::operator=(const job_path_report& a_class)
00472 {
00473 assign(a_class);
00474 return(*this);
00475 }
00476
00477
00478
00479
00480 const char *reportio::tags[] = {
00481 "[RSYNC]: ",
00482 "[REPORT]: ",
00483 0
00484 };
00485
00486
00487
00488 void reportio::write_rsync_out(const std::string& a_str)
00489 {
00490 std::cout.flush();
00491 std::cout << tags[rsync] << a_str << std::endl;
00492 std::cout.flush();
00493 }
00494
00495
00496
00497 void reportio::write_rsync_err(const std::string& a_str)
00498 {
00499 std::cerr.flush();
00500 std::cerr << tags[rsync] << a_str << std::endl;
00501 std::cerr.flush();
00502 }
00503
00504
00505
00506 void reportio::write_report(
00507 const std::string a_source,
00508 const timer& a_timer,
00509 const int a_exit_code,
00510 const int a_signal_num,
00511 const std::string& a_error_msg
00512 )
00513 {
00514 estring str;
00515
00516 str += estring(a_source.size());
00517 str += " ";
00518 str += a_source;
00519 str += " ";
00520 str += estring(static_cast<uint64>(a_timer.start_value()));
00521 str += " ";
00522 str += estring(static_cast<uint64>(a_timer.stop_value()));
00523 str += " ";
00524 str += estring(a_exit_code);
00525 str += " ";
00526 str += estring(a_signal_num);
00527 str += " ";
00528 str += estring(a_error_msg.size());
00529 str += " ";
00530 str += a_error_msg;
00531 str += " ";
00532
00533 std::cout.flush();
00534 std::cout << tags[report] << str << std::endl;
00535 std::cout.flush();
00536 }
00537
00538
00539
00540 job_path_report reportio::parse(const std::string& a_str)
00541 {
00542 estring es;
00543 job_path_report jpr;
00544 estring estr;
00545 estring::size_type idx;
00546 estring::size_type size;
00547 estring tmp;
00548 estring source;
00549 timer::value_type start_time;
00550 timer::value_type stop_time;
00551 int exit_code;
00552 int signal_num;
00553 estring error_msg;
00554
00555 TRY_nomem(estr = a_str);
00556 idx = estr.find(tags[report]);
00557 if (idx == std::string::npos) {
00558 estring es;
00559
00560 es = "Invalid job report: \"";
00561 es += a_str;
00562 es += "\"";
00563
00564 throw(INTERNAL_ERROR(0,es));
00565 }
00566
00567
00568
00569 estr.erase(0,idx+strlen(tags[report]));
00570
00571 idx = estr.find(' ');
00572 tmp = estr.substr(0,idx);
00573 estr.erase(0,idx+1);
00574 size = tmp;
00575 source = estr.substr(0,size);
00576 estr.erase(0,size+1);
00577
00578 idx = estr.find(' ');
00579 tmp = estr.substr(0,idx);
00580 estr.erase(0,idx+1);
00581 start_time = static_cast<uint64>(tmp);
00582
00583 idx = estr.find(' ');
00584 tmp = estr.substr(0,idx);
00585 estr.erase(0,idx+1);
00586 stop_time = static_cast<uint64>(tmp);
00587
00588 idx = estr.find(' ');
00589 tmp = estr.substr(0,idx);
00590 estr.erase(0,idx+1);
00591 exit_code = tmp;
00592
00593 idx = estr.find(' ');
00594 tmp = estr.substr(0,idx);
00595 estr.erase(0,idx+1);
00596 signal_num = tmp;
00597
00598 idx = estr.find(' ');
00599 tmp = estr.substr(0,idx);
00600 estr.erase(0,idx+1);
00601 size = tmp;
00602 error_msg = estr.substr(0,size);
00603 estr.erase(0,size+1);
00604
00605 jpr.assign(
00606 source,
00607 timer(start_time,stop_time),
00608 exit_code,
00609 signal_num,
00610 error_msg
00611 );
00612
00613 return(jpr);
00614 }
00615
00616
00617 bool reportio::is_report(const std::string& a_class)
00618 {
00619 estring::size_type idx;
00620
00621 idx = a_class.find(tags[report]);
00622 if (idx == std::string::npos) {
00623 return(false);
00624 }
00625 return(true);
00626 }
00627
00628
00629
00630
00631 single_job_report::single_job_report()
00632 {
00633 clear();
00634 }
00635
00636
00637 single_job_report::~single_job_report()
00638 {
00639 }
00640
00641
00642 void single_job_report::clear(void)
00643 {
00644 m_reports.clear();
00645 m_id.erase();
00646 }
00647
00648
00649 void single_job_report::add_report(const job_path_report& a_class)
00650 {
00651 TRY_nomem(m_reports.push_back(a_class));
00652 }
00653
00654
00655 const std::vector<job_path_report>& single_job_report::reports(void) const
00656 {
00657 return(m_reports);
00658 }
00659
00660
00661 void single_job_report::id(const std::string& a_str)
00662 {
00663 TRY_nomem(m_id = a_str);
00664 }
00665
00666
00667 const std::string& single_job_report::id(void) const
00668 {
00669 return(m_id);
00670 }
00671
00672
00673
00674 const bool single_job_report::status(void) const
00675 {
00676 bool value = true;
00677 std::vector<job_path_report>::const_iterator jpri;
00678
00679 for (jpri = m_reports.begin(); jpri != m_reports.end(); ++jpri) {
00680 if (!jpri->status())
00681 value = false;
00682 }
00683
00684 return(value);
00685 }
00686
00687
00688
00689
00690 jobs_report::jobs_report()
00691 {
00692 clear();
00693 }
00694
00695
00696 jobs_report::~jobs_report()
00697 {
00698 }
00699
00700
00701 void jobs_report::clear(void)
00702 {
00703 m_jobs.clear();
00704 }
00705
00706
00707 void jobs_report::add_report(const single_job_report& a_class)
00708 {
00709 TRY_nomem(m_jobs.push_back(a_class));
00710 }
00711
00712
00713 const std::vector<single_job_report>& jobs_report::reports(void) const
00714 {
00715 return(m_jobs);
00716 }
00717
00718
00719 void jobs_report::write_report(std::ostream& a_out)
00720 {
00721 std::vector<single_job_report>::const_iterator ji;
00722 std::vector<job_path_report>::const_iterator jpi;
00723 estring estr;
00724 estring estr2;
00725 estring hsep;
00726 estring vsep;
00727 estring vsep2;
00728
00729 hsep.fillchar('-');
00730 vsep = " | ";
00731 vsep2 = "|";
00732
00733 for (ji = m_jobs.begin(); ji != m_jobs.end(); ++ji) {
00734 table t1, t2;
00735 bool first_line = true;
00736
00737 if (ji != m_jobs.begin())
00738 a_out << std::endl;
00739
00740 estr.align(estring::left);
00741 estr = "Job: ";
00742 estr += ji->id();
00743 t1 << estr;
00744 t1 << table_endl;
00745
00746 t1 << hsep;
00747 t1 << table_endl;
00748
00749 t2 << "Job" << vsep << "Path" << " " << " "
00750 << table_endl;
00751 t2 << "Status" << vsep << "Status" << " " << "Source"
00752 << table_endl;
00753 t2 << hsep << vsep << hsep << " " << hsep << table_endl;
00754
00755 for (jpi = ji->reports().begin(); jpi != ji->reports().end(); ++jpi) {
00756 if (jpi != ji->reports().begin())
00757 t2 << table_endl;
00758
00759 if (first_line) {
00760 if (ji->status())
00761 t2 << "OK";
00762 else
00763 t2 << "ERROR";
00764 first_line = false;
00765 }
00766 else {
00767 t2 << " " << vsep << " " << " " << table_endl << " ";
00768 }
00769
00770 t2 << table_repeat << vsep;
00771
00772 if (jpi->status())
00773 t2 << "OK";
00774 else
00775 t2 << "ERROR";
00776
00777 t2 << " ";
00778
00779 t2 << jpi->source();
00780
00781 t2 << table_endl;
00782
00783 t2 << " " << table_repeat << vsep << " " << " ";
00784
00785 table t3, t4;
00786
00787 t3 << "+" << hsep << hsep << table_endl;
00788 t3 << table_repeat << vsep2 << " ";
00789
00790 estr.align(estring::right);
00791 estr2.align(estring::right);
00792
00793 estr = "Start:";
00794 estr2 = jpi->time().started_at();
00795 estr2 += " ";
00796 t4 << " " << estr << " " << estr2 << table_endl;
00797
00798 estr = "Finish:";
00799 estr2 = jpi->time().stopped_at();
00800 estr2 += " ";
00801 t4 << " " << estr << " " << estr2 << table_endl;
00802
00803 estr = "Duration:";
00804 estr2 = jpi->time().duration();
00805 t4 << " " << estr << " " << estr2 << table_endl;
00806
00807 t3 << t4 << table_endl;
00808
00809 estr2.align(estring::left);
00810 if (!jpi->status()) {
00811 table t5;
00812
00813 t3 << vsep2 << " " << " " << table_endl;
00814 t3 << table_repeat << vsep2 << " ";
00815
00816 estr = "Exit Code:";
00817 estr2 = estring(jpi->exit_code());
00818 if (jpi->exit_code() != 0) {
00819 estr2 += " ";
00820 estr2 += rsync_estat_str.exit(jpi->exit_code());
00821 }
00822 t5 << " " << estr << " " << estr2 << table_endl;
00823
00824 estr = "Signal Num:";
00825 estr2 = estring(jpi->signal_num());
00826 if (jpi->signal_num() != 0) {
00827 estr2 += " ";
00828 estr2 += rsync_estat_str.signal(jpi->signal_num());
00829 }
00830 t5 << " " << estr << " " << estr2 << table_endl;
00831
00832 if (jpi->error_msg().size() > 0) {
00833 estr = "Error Msg:";
00834 estr2 = jpi->error_msg();
00835 t5 << " " << estr << " " << estr2 << table_endl;
00836 }
00837
00838 t3 << t5;
00839 }
00840
00841
00842
00843 t2 << t3;
00844 }
00845
00846 t1 << t2;
00847
00848 a_out << t1;
00849 }
00850 }
00851
00852
00853 void jobs_report::format_synopsis(table& a_table)
00854 {
00855 estring estr, estr2;
00856 std::vector<single_job_report>::const_iterator sjri;
00857 uint16 jobs_good = 0;
00858 uint16 jobs_bad = 0;
00859 uint16 jobs_total = 0;
00860
00861 estr.align(estring::right);
00862
00863 for (sjri = m_jobs.begin(); sjri != m_jobs.end(); ++sjri) {
00864 if (sjri->status())
00865 ++jobs_good;
00866 else
00867 ++jobs_bad;
00868 ++jobs_total;
00869 }
00870
00871 estr = "Successful Jobs:";
00872 estr2 = estring(jobs_good);
00873 estr2 += " out of ";
00874 estr2 += estring(m_jobs.size());
00875 estr2 += " (";
00876 estr2 += percent_string(jobs_good, jobs_total);
00877 estr2 += ")";
00878
00879 a_table << estr << " " << estr2 << table_endl;
00880 }
00881
00882
00883
00884
00885 report_manager::report_manager()
00886 {
00887 m_initialized = false;
00888 }
00889
00890
00891 report_manager::~report_manager()
00892 {
00893 }
00894
00895
00896 void report_manager::init(void)
00897 {
00898 if (!config.initialized()) {
00899 throw(INTERNAL_ERROR(0,"Configuration manager is not initialized"));
00900 }
00901 m_initialized = true;
00902 }
00903
00904
00905 const bool report_manager::initialized(void) const
00906 {
00907 return(m_initialized);
00908 }
00909
00910
00911 void report_manager::clear(void)
00912 {
00913 m_total_time.clear();
00914 m_vault.clear();
00915 m_jobs.clear();
00916 }
00917
00918
00919 void report_manager::set_total_time(const timer& a_class)
00920 {
00921 if (!initialized())
00922 throw(INTERNAL_ERROR(0,"Report manager is not initialized"));
00923
00924 m_total_time = a_class;
00925 }
00926
00927
00928 vault_report& report_manager::vault(void)
00929 {
00930 return(m_vault);
00931 }
00932
00933
00934 jobs_report& report_manager::jobs(void)
00935 {
00936 return(m_jobs);
00937 }
00938
00939
00940 void report_manager::print_report(void)
00941 {
00942 estring lstr;
00943
00944 if (!initialized())
00945 throw(INTERNAL_ERROR(0,"Report manager is not initialized"));
00946
00947 lstr = "Reporter - Printing report to stdout...\n";
00948 logger.write(lstr);
00949
00950 write_report(std::cout);
00951
00952 lstr = "Reporter - Done\n";
00953 logger.write(lstr);
00954 }
00955
00956
00957 void report_manager::file_report(void)
00958 {
00959 std::ofstream out;
00960 std::string filename;
00961 std::string es;
00962 estring lstr;
00963 bool done = false;
00964 int count = 0;
00965
00966 if (!initialized())
00967 throw(INTERNAL_ERROR(0,"Report manager is not initialized"));
00968
00969 while (!done) {
00970 TRY_nomem(filename = config.log_dir());
00971 TRY_nomem(filename += "/");
00972 TRY_nomem(filename += config.timestamp().str());
00973 TRY_nomem(filename += ".report");
00974 if (count != 0) {
00975 TRY_nomem(filename += ".");
00976 TRY_nomem(filename += estring(count));
00977 }
00978 if (exists(filename))
00979 ++count;
00980 else
00981 done = true;
00982 }
00983 out.open(filename.c_str());
00984 if (!out.is_open()) {
00985 TRY_nomem(es = "Could not open report file: \"");
00986 TRY_nomem(es += filename);
00987 TRY_nomem(es += "\"");
00988 throw(ERROR(errno,es));
00989 }
00990
00991 lstr = "Reporter - Writing report to file...\n";
00992 logger.write(lstr);
00993 write_report(out);
00994
00995 out.close();
00996
00997 lstr = "Reporter - Done\n";
00998 logger.write(lstr);
00999 }
01000
01001
01002 void report_manager::write_report(std::ostream& a_out)
01003 {
01004 estring estr;
01005 estring es;
01006
01007 mf_write_header(a_out);
01008
01009 a_out << std::endl;
01010
01011 mf_write_synopsis(a_out);
01012
01013 a_out << std::endl;
01014
01015 m_jobs.write_report(a_out);
01016
01017 a_out << std::endl;
01018
01019 m_vault.write_report(a_out);
01020
01021 a_out << std::endl;
01022 }
01023
01024
01025 void report_manager::format_synopsis(table& a_table)
01026 {
01027 estring estr;
01028 estring estr2;
01029
01030 estr.align(estring::right);
01031 estr2.align(estring::right);
01032
01033 estr = "Start Time:";
01034 estr2 = m_total_time.started_at();
01035 estr2 += " ";
01036
01037 a_table << estr << " " << estr2 << table_endl;
01038
01039 estr = "Finish Time:";
01040 estr2 = m_total_time.stopped_at();
01041 estr2 += " ";
01042
01043 a_table << estr << " " << estr2 << table_endl;
01044
01045 estr = "Duration:";
01046 estr2 = m_total_time.duration();
01047
01048 a_table << estr << " " << estr2 << table_endl;
01049 }
01050
01051 void report_manager::mf_write_header(std::ostream& a_out)
01052 {
01053 table t;
01054 estring estr;
01055
01056 estr = "Rsync Vault Manager - ";
01057 estr += VERSION;
01058
01059 t << estr << table_endl;
01060
01061 estr = "";
01062 estr.fillchar('=');
01063 t << estr;
01064
01065 a_out << t;
01066 }
01067
01068 void report_manager::mf_write_synopsis(std::ostream& a_out)
01069 {
01070 table t;
01071 estring estr;
01072
01073 format_synopsis(t);
01074 vault().format_synopsis(t);
01075 jobs().format_synopsis(t);
01076
01077 a_out << t;
01078 }
01079
01080
01081
01082
01083 report_manager reporter;
01084