Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / tools / cephfs / EventOutput.cc
1 // -*- mode:c++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- 
2 // vim: ts=8 sw=2 smarttab
3 /*
4  * ceph - scalable distributed file system
5  *
6  * copyright (c) 2014 john spray <john.spray@inktank.com>
7  *
8  * this is free software; you can redistribute it and/or
9  * modify it under the terms of the gnu lesser general public
10  * license version 2.1, as published by the free software
11  * foundation.  see file copying.
12  */
13
14
15 #include <iostream>
16 #include <fstream>
17
18 #include "common/errno.h"
19 #include "mds/mdstypes.h"
20 #include "mds/events/EUpdate.h"
21 #include "mds/LogEvent.h"
22 #include "JournalScanner.h"
23
24 #include "EventOutput.h"
25
26
27 int EventOutput::binary() const
28 {
29   // Binary output, files
30   int r = ::mkdir(path.c_str(), 0755);
31   if (r != 0) {
32     r = -errno;
33     if (r != -EEXIST) {
34       std::cerr << "Error creating output directory: " << cpp_strerror(r) << std::endl;
35       return r;
36     }
37   }
38
39   for (JournalScanner::EventMap::const_iterator i = scan.events.begin(); i != scan.events.end(); ++i) {
40     LogEvent *le = i->second.log_event;
41     bufferlist le_bin;
42     le->encode(le_bin, CEPH_FEATURES_SUPPORTED_DEFAULT);
43
44     std::stringstream filename;
45     filename << "0x" << std::hex << i->first << std::dec << "_" << le->get_type_str() << ".bin";
46     std::string const file_path = path + std::string("/") + filename.str();
47     std::ofstream bin_file(file_path.c_str(), std::ofstream::out | std::ofstream::binary);
48     le_bin.write_stream(bin_file);
49     bin_file.close();
50     if (bin_file.fail()) {
51       return -EIO;
52     }
53   }
54   std::cerr << "Wrote output to binary files in directory '" << path << "'" << std::endl;
55
56   return 0;
57 }
58
59 int EventOutput::json() const
60 {
61   JSONFormatter jf(true);
62   std::ofstream out_file(path.c_str(), std::ofstream::out);
63   jf.open_array_section("journal");
64   {
65     for (JournalScanner::EventMap::const_iterator i = scan.events.begin(); i != scan.events.end(); ++i) {
66       LogEvent *le = i->second.log_event;
67       jf.open_object_section("log_event");
68       {
69         le->dump(&jf);
70       }
71       jf.close_section();  // log_event
72     }
73   }
74   jf.close_section();  // journal
75   jf.flush(out_file);
76   out_file.close();
77
78   if (out_file.fail()) {
79     return -EIO;
80   } else {
81     std::cerr << "Wrote output to JSON file '" << path << "'" << std::endl;
82     return 0;
83   }
84 }
85
86 void EventOutput::list() const
87 {
88   for (JournalScanner::EventMap::const_iterator i = scan.events.begin(); i != scan.events.end(); ++i) {
89     std::vector<std::string> ev_paths;
90     EMetaBlob const *emb = i->second.log_event->get_metablob();
91     if (emb) {
92       emb->get_paths(ev_paths);
93     }
94
95     std::string detail;
96     if (i->second.log_event->get_type() == EVENT_UPDATE) {
97       EUpdate *eu = reinterpret_cast<EUpdate*>(i->second.log_event);
98       detail = eu->type;
99     }
100
101     std::cout << "0x"
102       << std::hex << i->first << std::dec << " "
103       << i->second.log_event->get_type_str() << ": "
104       << " (" << detail << ")" << std::endl;
105     for (std::vector<std::string>::iterator i = ev_paths.begin(); i != ev_paths.end(); ++i) {
106         std::cout << "  " << *i << std::endl;
107     }
108   }
109 }
110
111 void EventOutput::summary() const
112 {
113   std::map<std::string, int> type_count;
114   for (JournalScanner::EventMap::const_iterator i = scan.events.begin(); i != scan.events.end(); ++i) {
115     std::string const type = i->second.log_event->get_type_str();
116     if (type_count.count(type) == 0) {
117       type_count[type] = 0;
118     }
119     type_count[type] += 1;
120   }
121
122   std::cout << "Events by type:" << std::endl;
123   for (std::map<std::string, int>::iterator i = type_count.begin(); i != type_count.end(); ++i) {
124       std::cout << "  " << i->first << ": " << i->second << std::endl;
125   }
126
127   std::cout << "Errors: " << scan.errors.size() << std::endl;
128   if (!scan.errors.empty()) {
129     for (JournalScanner::ErrorMap::const_iterator i = scan.errors.begin();
130          i != scan.errors.end(); ++i) {
131       std::cout << "  0x" << std::hex << i->first << std::dec
132                 << ": " << i->second.r << " "
133                 << i->second.description << std::endl;
134     }
135   }
136 }