TTKMusicPlayer  4.3.0.0
TTKMusicPlayer imitates Kugou UI, the music player uses of qmmp core library based on Qt for windows and linux
ttklogoutput.cpp
Go to the documentation of this file.
1 #include "ttklogoutput.h"
2 #include "ttksingleton.h"
3 
4 #include <QDir>
5 #include <QApplication>
6 
7 #if !TTK_QT_VERSION_CHECK(5,0,0)
9 using QtMessageHandler = QtMsgHandler;
10 #define qInstallMessageHandler qInstallMsgHandler
11 #endif
12 
14 {
16 public:
20  void initialize(const QString &module);
24  void install();
28  void uninstall();
29 
33  void setMaxSize(size_t maxSize) noexcept;
37  void setExpireSecond(size_t maxSecond) noexcept;
41  void setOutputPath(const QString &dir) noexcept;
42 
46 #if TTK_QT_VERSION_CHECK(5,0,0)
47  static void loggerHandler(QtMsgType type, const QMessageLogContext &context, const QString &message);
48 #else
49  static void loggerHandler(QtMsgType type, const char *message);
50 #endif
51 
52 private:
56  TTKLogOutput();
60  ~TTKLogOutput();
61 
65  void open();
69  void save(const QString &message);
73  void write(QtMsgType type, const QMessageLogContext &context, const QString &message);
74 
75 private:
76  QFile m_file;
79  QMutex m_mutex;
81 
82 };
83 
84 
86  : m_file(),
87  m_maxSize(5 * 1024 * 1024),
88  m_maxSecond(7 * 24 * 3600),
90  m_dateTime(TTK_DATE_FORMAT),
91 #ifdef Q_OS_WIN
92  m_outputDir(QString::fromLocal8Bit(qgetenv("APPDATA")) + TTK_SEPARATOR + "ttk/"),
93 #else
94  m_outputDir(QDir::homePath() + TTK_SEPARATOR + ".config/ttk/"),
95 #endif
96  m_mutex(),
97  m_defaultHandler(nullptr)
98 {
99 
100 }
101 
103 {
104  if(m_file.isOpen())
105  {
106  m_file.close();
107  }
108 }
109 
110 void TTKLogOutput::initialize(const QString &module)
111 {
112  if(!module.isEmpty())
113  {
114  m_module = module + "_";
115  }
116  else
117  {
118  m_module.clear();
119  }
120 }
121 
122 static void removeFiles(const QString &path, const qint64 time)
123 {
124  QDir dir(path);
125  for(const QFileInfo &fin : dir.entryInfoList())
126  {
127  const QString &fileName = fin.fileName();
128  if(fileName == "." || fileName == ".." || fin.suffix() != "log")
129  {
130  continue;
131  }
132 
133 #if TTK_QT_VERSION_CHECK(5,10,0)
134  const qint64 old = fin.birthTime().toMSecsSinceEpoch();
135 #else
136  const qint64 old = fin.created().toMSecsSinceEpoch();
137 #endif
138  const qint64 current = QDateTime::currentMSecsSinceEpoch();
139  if((current - old) / 1000 > time)
140  {
141  QFile::remove(fin.absoluteFilePath());
142  }
143  }
144 }
145 
147 {
148  if(m_defaultHandler)
149  {
150  return;
151  }
152 
153  const QDir dir(m_outputDir);
154  if(!dir.exists())
155  {
156  dir.mkdir(m_outputDir);
157  }
158 
159  // remove old history
161 
162  // open new log handler
163  open();
164 
166 }
167 
169 {
170  if(m_defaultHandler)
171  {
172  m_defaultHandler = nullptr;
174 
175  m_file.close();
176  }
177 }
178 
179 void TTKLogOutput::setMaxSize(size_t maxSize) noexcept
180 {
181  m_maxSize = maxSize;
182 }
183 
184 void TTKLogOutput::setExpireSecond(size_t maxSecond) noexcept
185 {
186  m_maxSecond = maxSecond;
187 }
188 
189 void TTKLogOutput::setOutputPath(const QString &dir) noexcept
190 {
191  m_outputDir = dir + TTK_SEPARATOR;
192 }
193 
194 #if TTK_QT_VERSION_CHECK(5,0,0)
195 void TTKLogOutput::loggerHandler(QtMsgType type, const QMessageLogContext &context, const QString &message)
196 {
197  TTKSingleton<TTKLogOutput>::instance()->write(type, context, message);
198 }
199 #else
200 void TTKLogOutput::loggerHandler(QtMsgType type, const char *message)
201 {
202  TTKSingleton<TTKLogOutput>::instance()->write(type, {}, message);
203 }
204 #endif
205 
207 {
208  if(m_file.isOpen())
209  {
210  return;
211  }
212 
213  m_dateTime = QDate::currentDate().toString(TTK_DATE_FORMAT);
214  const QString &fileName = m_outputDir + m_module + m_dateTime;
215 
216  int index = 1;
217  do
218  {
219  m_file.setFileName(fileName + QString("_%1.log").arg(index++));
220  }
221  while(m_file.size() >= m_maxSize);
222 
223  if(!m_file.open(QIODevice::WriteOnly | QIODevice::Append))
224  {
225  TTK_ERROR_STREAM("Open log file failed: " << m_file.fileName());
226  }
227 }
228 
229 void TTKLogOutput::save(const QString &message)
230 {
231  if(m_file.isOpen())
232  {
233  QTextStream out(&m_file);
234  out << message << TTK_WLINEFEED;
235  m_file.flush();
236  }
237 }
238 
239 void TTKLogOutput::write(QtMsgType type, const QMessageLogContext &context, const QString &message)
240 {
241  Q_UNUSED(type);
242  Q_UNUSED(context);
243 
244  m_mutex.lock();
245 
246  // output to console
247 #if TTK_QT_VERSION_CHECK(5,5,0)
248  if(type == QtDebugMsg || type == QtWarningMsg || type == QtInfoMsg)
249 #else
250  if(type == QtDebugMsg || type == QtWarningMsg)
251 #endif
252  {
253  QTextStream(stdout) << message << QtNamespace(endl);
254  }
255  else
256  {
257  QTextStream(stderr) << message << QtNamespace(endl);
258  }
259 
260  // output to file
261  if(m_file.isOpen())
262  {
263  const QString &date = QDate::currentDate().toString(TTK_DATE_FORMAT);
264  const bool moreLarge = m_file.size() >= m_maxSize;
265  const bool nextDate = date.compare(m_dateTime, Qt::CaseInsensitive) != 0;
266 
267  if(moreLarge || nextDate)
268  {
269  m_file.close();
270  open();
271  }
272  }
273 
274  save(message);
275  m_mutex.unlock();
276 }
277 
278 
279 void TTK::initiailizeLog(const QString &module)
280 {
281  TTKSingleton<TTKLogOutput>::instance()->initialize(module);
282 }
283 
285 {
287 }
288 
290 {
292 }
293 
294 void TTK::setLogMaxSize(qint64 maxSize)
295 {
296  TTKSingleton<TTKLogOutput>::instance()->setMaxSize(maxSize);
297 }
298 
299 void TTK::setExpireSecond(qint64 maxSecond)
300 {
301  TTKSingleton<TTKLogOutput>::instance()->setExpireSecond(maxSecond);
302 }
303 
304 void TTK::setOutputPath(const QString &dir)
305 {
306  TTKSingleton<TTKLogOutput>::instance()->setOutputPath(dir);
307 }
static QString message(const TTK::Attribute attr)
qint64 m_maxSize
void setMaxSize(size_t maxSize) noexcept
#define TTK_DEFAULT_STR
Definition: ttkglobal.h:276
TTK_MODULE_EXPORT void setOutputPath(const QString &dir)
#define qInstallMessageHandler
void save(const QString &message)
TTK_MODULE_EXPORT void initiailizeLog(const QString &module)
static void removeFiles(const QString &path, const qint64 time)
TTK_MODULE_EXPORT void installLogHandler()
QtMsgHandler QtMessageHandler
Definition: ttklogoutput.cpp:9
#define TTK_NAN_STR
Definition: ttkglobal.h:277
TTK_MODULE_EXPORT void removeLogHandler()
#define TTK_DECLARE_SINGLETON_CLASS(Class)
// Singleton Macro // //
Definition: ttksingleton.h:86
static T * instance()
Definition: ttksingleton.h:64
#define TTK_SEPARATOR
Definition: ttkglobal.h:269
qint64 m_maxSecond
void write(QtMsgType type, const QMessageLogContext &context, const QString &message)
#define TTK_DATE_FORMAT
Definition: ttkglobal.h:309
#define QtNamespace(p)
Qt use namespace.
Definition: ttkqtcompat.h:129
void initialize(const QString &module)
void setOutputPath(const QString &dir) noexcept
#define TTK_WLINEFEED
Definition: ttkglobal.h:272
QtMessageHandler m_defaultHandler
static void loggerHandler(QtMsgType type, const char *message)
#define TTK_STR_CAT(...)
Definition: ttkglobal.h:240
QString m_dateTime
#define TTK_ERROR_STREAM(msg)
Definition: ttklogger.h:76
QString m_module
TTK_MODULE_EXPORT void setLogMaxSize(qint64 maxSize)
void setExpireSecond(size_t maxSecond) noexcept
TTK_MODULE_EXPORT void setExpireSecond(qint64 maxSecond)
QString m_outputDir