GGS(GenericGEANT4Simulation)Software  2.99.0
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Macros
GGSSmartLog.cpp
1 /*
2  * SmartLog.cpp
3  *
4  * Created on: 24 Nov 2014
5  * Author: Nicola Mori
6  */
7 
8 #include "utils/GGSSmartLog.h"
9 
10 #ifdef GGS_USE_G4
11 #include "G4strstreambuf.hh"
12 #endif
13 
14 #include <fstream>
15 
16 namespace GGSSmartLog {
17 
18 const char *levelNames[6] = {"", "ERROR", "WARNING", "INFO", "DEBUG", "DEEPDEB"};
19 int verboseLevel = INFO;
20 int maxRoutineNameLength = 30;
21 
22 const std::string &Format(const std::string &str, unsigned int maxLength) {
23  static std::string returnStr;
24  returnStr = str;
25  if (returnStr.length() > maxLength) {
26  returnStr = returnStr.substr(0, maxLength - 3).append("...");
27  }
28  return returnStr;
29 }
30 
31 // Mute-unmute routines.
32 // From: https://bbs.archlinux.org/viewtopic.php?id=79378
33 // Modified to mute also C-style output and G4 thread-safe output.
34 
35 namespace {
36 
37 // Backup buffers for regular console output
38 FILE *stdoutSave = nullptr;
39 FILE *stderrSave = nullptr;
40 
41 std::streambuf *cout_sbuf = nullptr;
42 std::streambuf *cerr_sbuf = nullptr;
43 
44 bool isMuted = false;
45 
46 // Backup buffers for G4 console output
47 #ifdef GGS_USE_G4
48 G4ThreadLocal G4coutDestination *g4cout_dest = nullptr;
49 G4ThreadLocal G4coutDestination *g4cerr_dest = nullptr;
50 class MutecoutDestination : public G4coutDestination {
51 public:
52  G4int ReceiveG4cout(const G4String &) override { return 0; }
53  G4int ReceiveG4cerr(const G4String &) override { return 0; }
54 };
55 
56 MutecoutDestination g4MuteDest;
57 G4ThreadLocal bool isThreadMuted = false;
58 #endif
59 
60 class FilesProxy {
61 public:
62  FilesProxy() : fout("/dev/null"), muteOut(fopen("/dev/null", "w")) {}
63  ~FilesProxy() {
64  fout.close();
65  fclose(muteOut);
66  }
67  std::ofstream fout;
68  FILE *muteOut;
69 #ifdef GGS_USE_G4
70  MutecoutDestination g4MuteDest;
71 #endif
72 };
73 
74 FilesProxy muteFiles;
75 
76 } // namespace
77 
78 void MuteOutput() {
79 
80  if (!isMuted) {
81  stdoutSave = stdout;
82  stdout = muteFiles.muteOut;
83  stderrSave = stderr;
84  stderr = muteFiles.muteOut;
85 
86  cout_sbuf = std::cout.rdbuf();
87  cerr_sbuf = std::cerr.rdbuf();
88  std::cout.rdbuf(muteFiles.fout.rdbuf());
89  std::cerr.rdbuf(muteFiles.fout.rdbuf());
90 
91  isMuted = true;
92  }
93 }
94 
95 void UnmuteOutput() {
96  if (stdoutSave) {
97  stdout = stdoutSave;
98  stdoutSave = nullptr;
99  }
100  if (stderrSave) {
101  stderr = stderrSave;
102  stderrSave = nullptr;
103  }
104 
105  if (cout_sbuf) {
106  std::cout.rdbuf(cout_sbuf);
107  cout_sbuf = nullptr;
108  }
109  if (cerr_sbuf) {
110  std::cerr.rdbuf(cerr_sbuf);
111  cerr_sbuf = nullptr;
112  }
113 
114  isMuted = false;
115 }
116 
117 #ifdef GGS_USE_G4
118 void MuteG4Output() {
119 
120  if (!isThreadMuted) {
121  g4cout_dest = G4coutbuf.GetDestination();
122  G4coutbuf.SetDestination(&muteFiles.g4MuteDest);
123  g4cerr_dest = G4cerrbuf.GetDestination();
124  G4cerrbuf.SetDestination(&muteFiles.g4MuteDest);
125 
126  isThreadMuted = true;
127  }
128 }
129 
130 void UnmuteG4Output() {
131  if (g4cout_dest) {
132  G4coutbuf.SetDestination(g4cout_dest);
133  g4cout_dest = nullptr;
134  }
135  if (g4cerr_dest) {
136  G4cerrbuf.SetDestination(g4cerr_dest);
137  g4cout_dest = nullptr;
138  }
139 
140  isThreadMuted = false;
141 }
142 
143 #endif
144 
145 } // namespace GGSSmartLog