Krita Source Code Documentation
Loading...
Searching...
No Matches
KisUsageLogger Class Reference

The KisUsageLogger class logs messages to a logfile. More...

#include <KisUsageLogger.h>

Classes

struct  Private
 

Public Member Functions

 KisUsageLogger ()
 
 ~KisUsageLogger ()
 

Static Public Member Functions

static QString basicSystemInfo ()
 
static void close ()
 
static void initialize ()
 
static void log (const QString &message)
 Logs with date/time.
 
static QString screenInformation ()
 Returns information about all available screens.
 
static void writeHeader ()
 
static void writeLocaleSysInfo ()
 
static void writeSysInfo (const QString &message)
 Writes to the system information file and Krita log.
 

Private Member Functions

void rotateLog ()
 

Private Attributes

const QScopedPointer< Privated
 

Static Private Attributes

static const int s_maxLogs {20}
 
static const QString s_sectionHeader
 

Detailed Description

The KisUsageLogger class logs messages to a logfile.

Definition at line 17 of file KisUsageLogger.h.

Constructor & Destructor Documentation

◆ KisUsageLogger()

KisUsageLogger::KisUsageLogger ( )

Definition at line 59 of file KisUsageLogger.cpp.

60 : d(new Private)
61{
62 if (!QFileInfo(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation)).exists()) {
63 QDir().mkpath(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation));
64 }
65 d->logFile.setFileName(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + "/krita.log");
66 d->sysInfoFile.setFileName(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + "/krita-sysinfo.log");
67
68 QFileInfo fi(d->logFile.fileName());
69 if (fi.size() > 100 * 1000 * 1000) { // 100 mb seems a reasonable max
70 d->logFile.open(QIODevice::WriteOnly | QIODevice::Truncate);
71 d->logFile.close();
72 }
73 else {
74 rotateLog();
75 }
76
77 d->logFile.open(QFile::Append | QFile::Text);
78 d->sysInfoFile.open(QFile::WriteOnly | QFile::Text);
79}
const QScopedPointer< Private > d

References d, and rotateLog().

◆ ~KisUsageLogger()

KisUsageLogger::~KisUsageLogger ( )

Definition at line 81 of file KisUsageLogger.cpp.

82{
83 if (d->active) {
84 close();
85 }
86}
static void close()

References close(), and d.

Member Function Documentation

◆ basicSystemInfo()

QString KisUsageLogger::basicSystemInfo ( )
static

basic system information (there is other information spread in the code check usages of writeSysInfo for details)

Definition at line 96 of file KisUsageLogger.cpp.

97{
98 QString systemInfo;
99
100 // NOTE: This is intentionally not translated!
101
102 // Krita version info
103 systemInfo.append("Krita\n");
104 systemInfo.append("\n Version: ").append(KritaVersionWrapper::versionString(true));
105#ifdef Q_OS_WIN
106 {
107 using namespace KisWindowsPackageUtils;
108 QString packageFamilyName;
109 QString packageFullName;
110 systemInfo.append("\n Installation type: ");
111 if (tryGetCurrentPackageFamilyName(&packageFamilyName) && tryGetCurrentPackageFullName(&packageFullName)) {
112 systemInfo.append("Store / MSIX package\n Family Name: ")
113 .append(packageFamilyName)
114 .append("\n Full Name: ")
115 .append(packageFullName);
116 } else {
117 systemInfo.append("installer / portable package");
118 }
119 }
120#endif
121#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
122 // Attribute does nothing on Qt6
123 systemInfo.append("\n Hidpi: ").append(QCoreApplication::testAttribute(Qt::AA_EnableHighDpiScaling) ? "true" : "false");
124#endif
125#ifdef Q_OS_MACOS
126 KisMacosEntitlements entitlements;
127 systemInfo.append("\n Sandbox: ").append((entitlements.sandbox()) ? "true" : "false");
128#endif
129 systemInfo.append("\n\n");
130
131 systemInfo.append("Qt\n");
132 systemInfo.append("\n Version (compiled): ").append(QT_VERSION_STR);
133 systemInfo.append("\n Version (loaded): ").append(qVersion());
134 systemInfo.append("\n\n");
135
136 // OS information
137 systemInfo.append("OS Information\n");
138 systemInfo.append("\n Build ABI: ").append(QSysInfo::buildAbi());
139 systemInfo.append("\n Build CPU: ").append(QSysInfo::buildCpuArchitecture());
140 systemInfo.append("\n CPU: ").append(QSysInfo::currentCpuArchitecture());
141 systemInfo.append("\n Kernel Type: ").append(QSysInfo::kernelType());
142 systemInfo.append("\n Kernel Version: ").append(QSysInfo::kernelVersion());
143 systemInfo.append("\n Pretty Productname: ").append(QSysInfo::prettyProductName());
144 systemInfo.append("\n Product Type: ").append(QSysInfo::productType());
145 systemInfo.append("\n Product Version: ").append(QSysInfo::productVersion());
146
147#ifdef Q_OS_ANDROID
148 QString manufacturer =
149 QAndroidJniObject::getStaticObjectField("android/os/Build", "MANUFACTURER", "Ljava/lang/String;").toString();
150 const QString model =
151 QAndroidJniObject::getStaticObjectField("android/os/Build", "MODEL", "Ljava/lang/String;").toString();
152 manufacturer[0] = manufacturer[0].toUpper();
153 systemInfo.append("\n Product Model: ").append(manufacturer + " " + model);
154#elif defined(Q_OS_LINUX)
155 systemInfo.append("\n Desktop: ").append(qgetenv("XDG_CURRENT_DESKTOP"));
156
157 systemInfo.append("\n Appimage build: ").append(qEnvironmentVariableIsSet("APPIMAGE") ? "Yes" : "No");
158#elif defined(Q_OS_WIN)
159 systemInfo.append("\n Result of IsWindows10OrGreater(): ").append(IsWindows10OrGreater() ? "Yes" : "No");
160#endif
161 systemInfo.append("\n\n");
162
163 return systemInfo;
164}
bool tryGetCurrentPackageFullName(QString *outName)
bool tryGetCurrentPackageFamilyName(QString *outName)
KRITAVERSION_EXPORT QString versionString(bool checkGit=false)

References KisMacosEntitlements::sandbox(), and KritaVersionWrapper::versionString().

◆ close()

void KisUsageLogger::close ( )
static

Definition at line 209 of file KisUsageLogger.cpp.

210{
211 log("CLOSING SESSION");
212 s_instance->d->active = false;
213 s_instance->d->logFile.flush();
214 s_instance->d->logFile.close();
215 s_instance->d->sysInfoFile.flush();
216 s_instance->d->sysInfoFile.close();
217}
static void log(const QString &message)
Logs with date/time.

References log().

◆ initialize()

void KisUsageLogger::initialize ( )
static

Definition at line 88 of file KisUsageLogger.cpp.

89{
90 s_instance->d->active = true;
91
92 QString systemInfo = basicSystemInfo();
93 s_instance->d->sysInfoFile.write(systemInfo.toUtf8());
94}
static QString basicSystemInfo()

References basicSystemInfo().

◆ log()

void KisUsageLogger::log ( const QString & message)
static

Logs with date/time.

Definition at line 219 of file KisUsageLogger.cpp.

220{
221 QMutexLocker locker(&s_instance->d->mutex);
222
223 if (!s_instance->d->active) return;
224 if (!s_instance->d->logFile.isOpen()) return;
225
226 s_instance->d->logFile.write(QDateTime::currentDateTime().toString(Qt::RFC2822Date).toUtf8());
227 s_instance->d->logFile.write(": ");
228 s_instance->d->logFile.write(message.toUtf8());
229 s_instance->d->logFile.write("\n");
230 s_instance->d->logFile.flush();
231}
QString toString(const QString &value)

◆ rotateLog()

void KisUsageLogger::rotateLog ( )
private

Definition at line 309 of file KisUsageLogger.cpp.

310{
311 if (d->logFile.exists()) {
312 {
313 // Check for CLOSING SESSION
314 d->logFile.open(QFile::ReadOnly);
315 QString log = QString::fromUtf8(d->logFile.readAll());
316 if (!log.split(s_sectionHeader).last().contains("CLOSING SESSION")) {
317 log.append("\nKRITA DID NOT CLOSE CORRECTLY\n");
318 QString crashLog = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + QStringLiteral("/kritacrash.log");
319 if (QFileInfo(crashLog).exists()) {
320 QFile f(crashLog);
321 f.open(QFile::ReadOnly);
322 QString crashes = QString::fromUtf8(f.readAll());
323 f.close();
324
325 QStringList crashlist = crashes.split("-------------------");
326 log.append(QString("\nThere were %1 crashes in total in the crash log.\n").arg(crashlist.size()));
327
328 if (crashes.size() > 0) {
329 log.append(crashlist.last());
330 }
331 }
332 d->logFile.close();
333 d->logFile.open(QFile::WriteOnly);
334 d->logFile.write(log.toUtf8());
335 }
336 d->logFile.flush();
337 d->logFile.close();
338 }
339
340 {
341 // Rotate
342 d->logFile.open(QFile::ReadOnly);
343 QString log = QString::fromUtf8(d->logFile.readAll());
344 d->logFile.close();
345 QStringList logItems = log.split("SESSION:");
346 QStringList keptItems;
347 int sectionCount = logItems.size();
348 if (sectionCount > s_maxLogs) {
349 for (int i = sectionCount - s_maxLogs; i < sectionCount; ++i) {
350 if (logItems.size() > i ) {
351 keptItems.append(logItems[i]);
352 }
353 }
354
355 d->logFile.open(QFile::WriteOnly);
356 d->logFile.write(keptItems.join("\nSESSION:").toUtf8());
357 d->logFile.flush();
358 d->logFile.close();
359 }
360 }
361
362
363 }
364}
static const int s_maxLogs
static const QString s_sectionHeader

References d, log(), s_maxLogs, and s_sectionHeader.

◆ screenInformation()

QString KisUsageLogger::screenInformation ( )
static

Returns information about all available screens.

Definition at line 274 of file KisUsageLogger.cpp.

275{
276 QList<QScreen*> screens = qApp->screens();
277
278 QString info;
279 info.append("Display Information");
280 info.append("\nNumber of screens: ").append(QString::number(screens.size()));
281
282 for (int i = 0; i < screens.size(); ++i ) {
283 QScreen *screen = screens[i];
284 info.append("\n\tScreen: ").append(QString::number(i));
285 info.append("\n\t\tName: ").append(screen->name());
286 info.append("\n\t\tDepth: ").append(QString::number(screen->depth()));
287 info.append("\n\t\tScale: ").append(QString::number(screen->devicePixelRatio()));
288 info.append("\n\t\tPhysical DPI").append(QString::number(screen->physicalDotsPerInch()));
289 info.append("\n\t\tLogical DPI").append(QString::number(screen->logicalDotsPerInch()));
290 info.append("\n\t\tPhysical Size: ").append(QString::number(screen->physicalSize().width()))
291 .append(", ")
292 .append(QString::number(screen->physicalSize().height()));
293 info.append("\n\t\tPosition: ").append(QString::number(screen->geometry().x()))
294 .append(", ")
295 .append(QString::number(screen->geometry().y()));
296 info.append("\n\t\tResolution in pixels: ").append(QString::number(screen->geometry().width()))
297 .append("x")
298 .append(QString::number(screen->geometry().height()));
299 info.append("\n\t\tManufacturer: ").append(screen->manufacturer());
300 info.append("\n\t\tModel: ").append(screen->model());
301 info.append("\n\t\tRefresh Rate: ").append(QString::number(screen->refreshRate()));
302 info.append("\n\t\tSerial Number: ").append(screen->serialNumber());
303
304 }
305 info.append("\n");
306 return info;
307}

◆ writeHeader()

void KisUsageLogger::writeHeader ( )
static

Definition at line 247 of file KisUsageLogger.cpp.

248{
249 Q_ASSERT(s_instance->d->sysInfoFile.isOpen());
250 s_instance->d->logFile.write(s_sectionHeader.toUtf8());
251
252 QString sessionHeader = QString("SESSION: %1. Executing %2\n\n")
253 .arg(QDateTime::currentDateTime().toString(Qt::RFC2822Date))
254 .arg(qApp->arguments().join(' '));
255
256 s_instance->d->logFile.write(sessionHeader.toUtf8());
257
258 QString KritaAndQtVersion;
259 KritaAndQtVersion.append("Krita Version: ").append(KritaVersionWrapper::versionString(true))
260 .append(", Qt version compiled: ").append(QT_VERSION_STR)
261 .append(", loaded: ").append(qVersion())
262 .append(". Process ID: ")
263 .append(QString::number(qApp->applicationPid())).append("\n");
264
265 KritaAndQtVersion.append("-- -- -- -- -- -- -- --\n");
266 s_instance->d->logFile.write(KritaAndQtVersion.toUtf8());
267 s_instance->d->logFile.flush();
268 log(QString("Style: %1. Available styles: %2")
269 .arg(qApp->style()->objectName(),
270 QStyleFactory::keys().join(", ")));
271
272}

References log(), s_sectionHeader, and KritaVersionWrapper::versionString().

◆ writeLocaleSysInfo()

void KisUsageLogger::writeLocaleSysInfo ( )
static

Definition at line 166 of file KisUsageLogger.cpp.

167{
168 if (!s_instance->d->active) {
169 return;
170 }
171 QString systemInfo;
172 systemInfo.append("Locale\n");
173 systemInfo.append("\n Languages: ").append(KLocalizedString::languages().join(", "));
174 systemInfo.append("\n C locale: ").append(std::setlocale(LC_ALL, nullptr));
175 systemInfo.append("\n QLocale current: ").append(QLocale().bcp47Name());
176 systemInfo.append("\n QLocale system: ").append(QLocale::system().bcp47Name());
177 const QTextCodec *codecForLocale = QTextCodec::codecForLocale();
178 systemInfo.append("\n QTextCodec for locale: ").append(codecForLocale->name());
179#ifdef Q_OS_WIN
180 {
181 systemInfo.append("\n Process ACP: ");
182 CPINFOEXW cpInfo {};
183 if (GetCPInfoExW(CP_ACP, 0, &cpInfo)) {
184 systemInfo.append(QString::fromWCharArray(cpInfo.CodePageName));
185 } else {
186 // Shouldn't happen, but just in case
187 systemInfo.append(QString::number(GetACP()));
188 }
189 wchar_t lcData[2];
190 int result = GetLocaleInfoEx(LOCALE_NAME_SYSTEM_DEFAULT, LOCALE_IDEFAULTANSICODEPAGE | LOCALE_RETURN_NUMBER, lcData, sizeof(lcData) / sizeof(lcData[0]));
191 if (result == 2) {
192 systemInfo.append("\n System locale default ACP: ");
193 int systemACP = lcData[1] << 16 | lcData[0];
194 if (systemACP == CP_ACP) {
195 systemInfo.append("N/A");
196 } else if (GetCPInfoExW(systemACP, 0, &cpInfo)) {
197 systemInfo.append(QString::fromWCharArray(cpInfo.CodePageName));
198 } else {
199 // Shouldn't happen, but just in case
200 systemInfo.append(QString::number(systemACP));
201 }
202 }
203 }
204#endif
205 systemInfo.append("\n\n");
206 s_instance->d->sysInfoFile.write(systemInfo.toUtf8());
207}

◆ writeSysInfo()

void KisUsageLogger::writeSysInfo ( const QString & message)
static

Writes to the system information file and Krita log.

Definition at line 233 of file KisUsageLogger.cpp.

234{
235 QMutexLocker locker(&s_instance->d->mutex);
236
237 if (!s_instance->d->active) return;
238 if (!s_instance->d->sysInfoFile.isOpen()) return;
239
240 s_instance->d->sysInfoFile.write(message.toUtf8());
241 s_instance->d->sysInfoFile.write("\n");
242
243 s_instance->d->sysInfoFile.flush();
244
245}

Member Data Documentation

◆ d

const QScopedPointer<Private> KisUsageLogger::d
private

Definition at line 53 of file KisUsageLogger.h.

◆ s_maxLogs

const int KisUsageLogger::s_maxLogs {20}
staticprivate

Definition at line 56 of file KisUsageLogger.h.

56{20};

◆ s_sectionHeader

const QString KisUsageLogger::s_sectionHeader
staticprivate

Definition at line 55 of file KisUsageLogger.h.


The documentation for this class was generated from the following files: