/* This file is part of cputemp2maxfreq. Copyright (C) 2023-2024 pa4wdh cputemp2maxfreq is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License , or (at your option) any later version. cputemp2maxfreq is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with cputemp2maxfreq; see the file COPYING. If not, see . */ #include #include #include #include #include #include #include #include "cputemp2maxfreq.h" #include "debug.h" extern struct s_config config; extern struct s_cpudata cpudata; // The logger_* functions are not called directly. They are set by argparse in // the config.logger function pointer. // No logging at all void logger_none(char *format,...) { } // Logging to stdout void logger_stdout(char *format,...) { va_list args; struct timeval systime; struct tm *systime_tm; char timestring[255]; time_t unixtime; if (config.use_unixtime==0) { gettimeofday(&systime,NULL); systime_tm=localtime(&systime.tv_sec); strftime(timestring,sizeof(timestring),"%F %T",systime_tm); printf("%s: ",timestring); } else { unixtime=time(NULL); printf("%ld: ",unixtime); } va_start(args,format); vprintf(format,args); va_end(args); putchar(10); } // Logging to syslog void logger_syslog(char *format,...) { va_list args; va_start(args,format); vsyslog(LOG_DAEMON||LOG_CRIT,format,args); va_end(args); } // Logging to kernel log buffer (/dev/kmsg) void logger_kmsg(char *format,...) { va_list args; FILE *kmsg; char buffer[255]; kmsg=fopen("/dev/kmsg","w"); if (kmsg!=NULL) { fprintf(kmsg,"cputemp2maxfreq: "); va_start(args,format); vfprintf(kmsg,format,args); va_end(args); putc(10,kmsg); fclose(kmsg); } else { va_start(args,format); vsnprintf(buffer,sizeof(buffer),format,args); va_end(args); strcpy(config.logger_name,"stdout"); config.logger=&logger_stdout; config.logger("Failed to open /dev/kmsg, falling back to stdout logging"); config.logger(buffer); } } // CSV logging fields: // 1: Timestamp // 2: CPU Minimum frequency // 3: CPU Maximum frequency // 4: CPU Current frequency // 5: CPU Temperature // 6: Target temperature // 7: Scaling maximum frequency before increase/decrease void csvlog_init() { int exists; DEBUG1_LOG("Started\n"); exists=access(config.csvlog,F_OK); DEBUG1_LOG("File %s exists: %d\n",config.csvlog,exists); if ((exists!=0) || (config.csvoverwrite==1)) { DEBUG1_LOG("Creating/overwriting CSV file\n"); config.csvfile=fopen(config.csvlog,"w"); fputs("\"timestamp\"," "\"CPU Minumum frequency\"," "\"CPU Maximum frequency\"," "\"CPU Current frequency\"," "\"CPU Temperature\"," "\"Target Temperature\"," "\"Scaling maximum frequency\"\n",config.csvfile); fflush(config.csvfile); } else { DEBUG1_LOG("Appending to CSV file\n"); config.csvfile=fopen(config.csvlog,"a"); } } // Write a single line of CSV data void csvlog_write() { struct timeval systime; struct tm *systime_tm; char timestring[255]; time_t unixtime; DEBUG1_LOG("Writing data series to CSV file\n"); if (config.use_unixtime==0) { gettimeofday(&systime,NULL); systime_tm=localtime(&systime.tv_sec); strftime(timestring,sizeof(timestring),"\"%F %T\"",systime_tm); } else { unixtime=time(NULL); snprintf(timestring,sizeof(timestring),"%ld",unixtime); } fprintf(config.csvfile,"%s,\"%ld\",\"%ld\",\"%ld\",\"%ld\",\"%ld\",\"%ld\"\n",timestring,cpudata.min_freq,cpudata.max_freq,cpudata.cur_freq,cpudata.cur_temp/1000,config.target_temp/1000,cpudata.scale_max); fflush(config.csvfile); } // Close the CSV file void csvlog_close() { DEBUG1_LOG("Closing CSV file\n"); fclose(config.csvfile); config.csvfile=NULL; }