3 * (C) 2014-06-30 K.Ohta
5 * Dec 30, 2014 Move from XM7/SDL, this was Ohta's original code.
10 #include <QMutexLocker>
12 #include "csp_logger.h"
16 #include "menu_flags.h"
19 CSP_Logger::CSP_Logger(bool b_syslog, bool cons, const char *devname)
21 lock_mutex = new QMutex(QMutex::Recursive);
23 this->open(b_syslog, cons, devname);
27 CSP_Logger::~CSP_Logger()
35 void CSP_Logger::reset(void)
40 QMutexLocker locker(lock_mutex);
41 component_names.clear();
48 const char *components[] = {
68 for(int i = 0; ; i++) {
71 tmps = QString::fromUtf8(p);
72 component_names.append(tmps);
74 const char *vfiles[] = {
85 for(int i = 0; ; i++) {
90 tmps = QString::fromUtf8(p);
93 } else if(i == 7) { // QD
98 for(int j = 0; j < lim; j++) {
100 vfile_names.append(tmps + ss);
104 tmps = QString::fromUtf8("CPU"); // Enable to update
105 for(int i = 0; i < 8; i++) {
108 cpu_names.append(tmps + ss);
109 for(int j = 0; j < CSP_LOG_LEVELS; j++) {
110 level_cpu_out_record[i][j] = true;
111 level_cpu_out_syslog[i][j] = false;
112 level_cpu_out_console[i][j] = true;
115 tmps = QString::fromUtf8("DEV"); // Enable to update
116 for(int i = 0; i < (256 - (32 + 8)); i++) {
119 device_names.append(tmps + ss);
120 for(int j = 0; j < CSP_LOG_LEVELS; j++) {
121 level_dev_out_record[i][j] = true;
122 level_dev_out_syslog[i][j] = false;
123 level_dev_out_console[i][j] = true;
128 //extern class USING_FLAGS *using_flags;
129 void CSP_Logger::open(bool b_syslog, bool cons, const char *devname)
133 QMutexLocker locker(lock_mutex);
141 if(devname != NULL) {
142 dname = QString::fromUtf8(devname);
144 dname = QString::fromUtf8("*Undefined*");
146 log_sysname = QString::fromUtf8("Common Source Code Project(");
147 log_sysname = log_sysname + dname + QString::fromUtf8(")");
151 #if defined(_SYS_SYSLOG_H) || defined(_SYSLOG_H)
155 openlog(log_sysname.toLocal8Bit().constData(), flags | LOG_PID | LOG_NOWAIT, LOG_USER);
162 log_cons_out = log_cons;
163 syslog_flag_out = syslog_flag;
165 cons_log_levels = 1 << CSP_LOG_INFO;
169 this->debug_log(CSP_LOG_INFO, "Start logging.");
172 void CSP_Logger::debug_log(int level, const char *fmt, ...)
178 vsnprintf(strbuf, 4095, fmt, ap);
179 debug_log(level, 0, strbuf);
184 void CSP_Logger::debug_log(int level, int domain_num, const char *fmt, ...)
190 vsnprintf(strbuf, 4095, fmt, ap);
191 debug_log(level, domain_num, strbuf);
195 void CSP_Logger::debug_log(int level, int domain_num, char *strbuf)
203 if(!log_opened) return;
204 if(level < 0) level = 0;
205 if(level >= CSP_LOG_LEVELS) level = CSP_LOG_LEVELS - 1;
207 #if !defined(Q_OS_WIN)
208 int level_flag = LOG_USER;
209 if(level == CSP_LOG_DEBUG) {
210 level_flag |= LOG_DEBUG;
211 } else if(level == CSP_LOG_INFO) {
212 level_flag |= LOG_INFO;
213 } else if(level == CSP_LOG_WARN) {
214 level_flag |= LOG_WARNING;
216 level_flag |= LOG_DEBUG;
221 const char delim[2] = "\n";
223 QMutexLocker locker(lock_mutex);
225 p = strtok(strbuf, delim);
227 p = strtok_r(strbuf, delim, &p_bak);
231 nowtime = time(NULL);
232 gettimeofday(&tv, NULL);
233 if(log_cons != 0) { // Print only
234 timedat = localtime(&nowtime);
235 strftime(strbuf2, 255, "%Y-%m-%d %H:%M:%S", timedat);
236 snprintf(strbuf3, 23, ".%06ld", tv.tv_usec);
238 QString time_s = QString::fromUtf8(strbuf2) + QString::fromUtf8(strbuf3);
240 int cons_log_level_n = (1 << level) & cons_log_levels;
241 int sys_log_level_n = (1 << level) & sys_log_levels;
243 bool record_flag = true;
246 if((domain_num > 0) && (domain_num < CSP_LOG_TYPE_COMPONENT_END)) {
247 domain_s = component_names.at(domain_num - 1);
248 } else if((domain_num >= CSP_LOG_TYPE_VM_CPU0) && (domain_num < CSP_LOG_TYPE_VM_DEVICE_0)) {
249 domain_s = cpu_names.at(domain_num - CSP_LOG_TYPE_VM_CPU0);
251 record_flag = level_cpu_out_record[domain_num - CSP_LOG_TYPE_VM_CPU0][level];
252 if(!level_cpu_out_syslog[domain_num - CSP_LOG_TYPE_VM_CPU0][level]) sys_log_level_n = 0;
253 if(!level_cpu_out_console[domain_num - CSP_LOG_TYPE_VM_CPU0][level]) cons_log_level_n = 0;
254 } else if((domain_num >= CSP_LOG_TYPE_VM_DEVICE_0) && (domain_num <= CSP_LOG_TYPE_VM_DEVICE_END)) {
255 domain_s = device_names.at(domain_num - CSP_LOG_TYPE_VM_DEVICE_0);
257 record_flag = level_dev_out_record[domain_num - CSP_LOG_TYPE_VM_DEVICE_0][level];
258 if(!level_dev_out_syslog[domain_num - CSP_LOG_TYPE_VM_DEVICE_0][level]) sys_log_level_n = 0;
259 if(!level_dev_out_console[domain_num - CSP_LOG_TYPE_VM_DEVICE_0][level]) cons_log_level_n = 0;
260 } else if((domain_num >= CSP_LOG_TYPE_VFILE_HEAD) && (domain_num < CSP_LOG_TYPE_VFILE_END)) {
261 domain_s = vfile_names.at(domain_num - CSP_LOG_TYPE_VFILE_HEAD);
263 if(!domain_s.isEmpty()) {
264 domain_s = QString::fromUtf8("[") + domain_s + QString::fromUtf8("]");
266 if(!log_cons || !log_cons_out) cons_log_level_n = 0;
267 if(!syslog_flag || !syslog_flag_out) sys_log_level_n = 0;
271 CSP_LoggerLine *tmps;
272 tmps = new CSP_LoggerLine(linenum, level, domain_s, time_s, QString::fromUtf8(p));
274 if(cons_log_level_n != 0) {
275 fprintf(stdout, "%s : %s\n",
276 log_sysname.toLocal8Bit().constData(),
277 tmps->get_element_console().toLocal8Bit().constData());
279 #if !defined(Q_OS_WIN)
280 if(sys_log_level_n != 0) {
281 syslog(level_flag, "uS=%06ld %s",
283 tmps->get_element_syslog().toLocal8Bit().constData());
288 QMutexLocker locker(lock_mutex);
290 p = strtok(NULL, delim);
292 p = strtok_r(NULL, delim, &p_bak);
298 QMutexLocker locker(lock_mutex);
299 squeue.enqueue(tmps);
300 if(linenum == LLONG_MAX) {
308 #if defined(Q_OS_WIN)
310 QMutexLocker locker(lock_mutex);
318 void CSP_Logger::set_log_status(bool sw)
323 void CSP_Logger::set_log_stdout(int level, bool sw)
325 if((level < 0) || (level >= 32)) {
331 cons_log_levels |= lv;
333 cons_log_levels &= ~lv;
337 void CSP_Logger::set_log_syslog(int level, bool sw)
339 if((level < 0) || (level >= 32)) {
340 syslog_flag_out = sw;
345 sys_log_levels |= lv;
347 sys_log_levels &= ~lv;
351 bool CSP_Logger::get_status(void)
357 void CSP_Logger::close(void)
359 QMutexLocker locker(lock_mutex);
362 #if !defined(Q_OS_WIN32)
363 if(syslog_flag != 0) {
368 syslog_flag_out = false;
371 log_cons_out = false;
375 while(!squeue.isEmpty()) {
376 CSP_LoggerLine *p = squeue.dequeue();
377 if(p != NULL) delete p;
384 void CSP_Logger::set_emu_vm_name(const char *devname)
387 if(devname != NULL) {
388 dname = QString::fromUtf8(devname);
390 dname = QString::fromUtf8("*Undefined*");
392 log_sysname = QString::fromUtf8("Common Source Code Project(");
393 log_sysname = log_sysname + dname + QString::fromUtf8(")");
396 void CSP_Logger::set_device_name(int num, char *devname)
400 if(num > (CSP_LOG_TYPE_VM_DEVICE_END - CSP_LOG_TYPE_VM_DEVICE_0)) return;
401 if(devname == NULL) {
404 tmps = QString::fromUtf8("Device#");
407 tmps = QString::fromUtf8(devname);
409 device_names.replace(num, tmps);
410 if(max_devices <= num) max_devices = num + 1;
413 void CSP_Logger::set_cpu_name(int num, char *devname)
416 if(num > (CSP_LOG_TYPE_VM_CPU7 - CSP_LOG_TYPE_VM_CPU0)) return;
417 if(devname == NULL) return;
418 QString tmps = QString::fromUtf8(devname);
419 device_names.replace(num, tmps);
420 if(max_cpus <= num) max_cpus = num + 1;
423 void CSP_Logger::set_device_node_log(int device_id, int to_output, int type, bool flag)
426 if(type >= CSP_LOG_LEVELS) return;
427 if(to_output < 0) return;
428 if(to_output > 2) return;
429 if(device_id >= (CSP_LOG_TYPE_VM_DEVICE_END - CSP_LOG_TYPE_VM_DEVICE_0)) return;
430 if(device_id == -1) { // Flush all device
431 for(int i = 0; i < (CSP_LOG_TYPE_VM_DEVICE_END - CSP_LOG_TYPE_VM_DEVICE_0 + 1); i++) {
432 // 0 = record, 1 = syslog, 2 = console;
436 level_dev_out_record[i][type] = flag;
439 level_dev_out_syslog[i][type] = flag;
442 level_dev_out_console[i][type] = flag;
449 // 0 = record, 1 = syslog, 2 = console;
453 level_dev_out_record[device_id][type] = flag;
456 level_dev_out_syslog[device_id][type] = flag;
459 level_dev_out_console[device_id][type] = flag;
467 void CSP_Logger::set_device_node_log(int to_output, int type, bool *flags, int start, int devices)
469 if(flags == NULL) return;
470 if(start < 0) return;
473 for(i = 0; i < devices; i++) {
474 set_device_node_log(i + start, to_output, type, flags[i]);
478 void CSP_Logger::set_device_node_log(int to_output, int type, int *flags, int start, int devices)
480 if(flags == NULL) return;
481 if(start < 0) return;
485 for(i = 0; i < devices; i++) {
486 f = (flags[i] == 0) ? false : true;
487 set_device_node_log(i + start, to_output, type, f);
491 void CSP_Logger::output_event_log(int device_id, int level, const char *fmt, ...)
496 p = (char *)(device_names.at(device_id).toLocal8Bit().constData());
500 vsnprintf(strbuf2, 4095, fmt, ap);
501 snprintf(strbuf, 4500, "[%s] %s", p, strbuf2);
502 debug_log(level, CSP_LOG_TYPE_EVENT, strbuf);
506 int64_t CSP_Logger::get_console_list(char *buffer, int64_t buf_size, bool utf8, char *domainname, bool forget, int64_t start, int64_t end)
508 if((buffer == NULL) || (buf_size <= 0)) return (int64_t)-1;
512 bool not_match_domain = false;
513 if(domainname == NULL) not_match_domain = true;
514 if(!not_match_domain && (domainname != NULL)) dom = QString::fromUtf8(domainname);
515 if(dom.isEmpty()) not_match_domain = true;
517 int64_t total_size = 0;
521 bool check_line = ((start >= 0) && (end >= start));
524 QMutexLocker locker(lock_mutex);
527 for(int i = 0; i < ssize; i++) {
529 QMutexLocker locker(lock_mutex);
530 if(squeue.isEmpty()) break;
531 t = squeue.dequeue();
533 QMutexLocker locker(lock_mutex);
538 int64_t n_line = t->get_line_num();
539 if((n_line < start) || (n_line >= end)) {
541 QMutexLocker locker(lock_mutex);
548 if(not_match_domain) {
549 tmps = t->get_element_console();
551 if(dom == t->get_domain()) {
552 tmps = t->get_element_console();
557 if(!tmps.isEmpty()) {
563 ns = tmps.toLocal8Bit();
567 memset(tmpbuf, 0x00, 8192);
568 if(l >= 8192) l = 8192 -1;
569 strncpy(tmpbuf, ns.constData(), l);
571 if(((int64_t)l + total_size) < buf_size) {
572 strncpy(pp, tmpbuf, l);
574 total_size += (int64_t)l;
577 QMutexLocker locker(lock_mutex);
584 QMutexLocker locker(lock_mutex);
592 void CSP_Logger::clear_log(void)
594 QMutexLocker locker(lock_mutex);
595 while(!squeue.isEmpty()) {
596 CSP_LoggerLine *p = squeue.dequeue();
597 if(p != NULL) delete p;
601 int64_t CSP_Logger::write_log(const _TCHAR *name, const char *domain_name, bool utf8, bool forget)
603 int64_t n_len = (int64_t)-1;
604 if(name == NULL) return n_len;
606 FILEIO *fio = new FILEIO();
607 if(fio == NULL) return n_len;
609 if(!fio->Fopen(name, FILEIO_READ_WRITE_BINARY)) {
613 if(fio->FileLength() > 0) fio->Fseek(0, FILEIO_SEEK_END);
615 char strbuf[0x20000];
618 memset(strbuf, 0x00, sizeof(strbuf));
619 len = get_console_list(strbuf, 0x20000, utf8, (char *)domain_name, forget);
620 if(len > 0x20000) break; // Illegal
622 if(fio->Fwrite(strbuf, (uint32_t)len, 1) != len) break;
630 int64_t CSP_Logger::copy_log(char *buffer, int64_t buf_size, int64_t *lines, char *domainname, bool utf8, bool forget, int64_t start, int64_t start_size)
632 if((buffer == NULL) || (buf_size <= 0)) return (int64_t)-1;
633 int64_t line = start;
635 int64_t buf_left = buf_size;
638 int64_t ssize = start_size;
639 if(ssize < 0) ssize = 0;
640 if(start_size >= buf_size) return -1;
642 char *p = &(buffer[start_size]);
644 if(line < 0) line = 0;
646 QMutexLocker locker(lock_mutex);
647 nlines = squeue.size();
649 for(; (buf_left > 0) && (nlines > 0);) {
650 size = get_console_list(buffer, buf_left, utf8, domainname, forget, line, line + 1);
658 if(lines != NULL) *lines = *lines + lines_t;