pull/69/merge
sfeakes 2023-06-23 19:38:59 -05:00
parent 4a6c948a6a
commit 642bfc3383
10 changed files with 154 additions and 33 deletions

View File

@ -235,6 +235,7 @@ struct aqualinkdata
unsigned char raw_status[AQ_PSTLEN];
// Multiple threads update this value.
volatile bool updated;
char self[AQ_MSGLEN*2];
#ifdef AQ_MANAGER
volatile bool run_slogger;

View File

@ -69,6 +69,7 @@ static volatile bool _restart = false;
//static struct aqconfig _aqconfig_;
static struct aqualinkdata _aqualink_data;
// NSF Need to remove self
char *_self;
char *_cfgFile;
int _cmdln_loglevel = -1;
@ -1153,6 +1154,7 @@ int startup(char *self, char *cfgFile)
_cfgFile = cfgFile;
//initButtons(&_aqualink_data);
sprintf(_aqualink_data.self, basename(self));
clearDebugLogMask();
read_config(&_aqualink_data, cfgFile);
@ -1372,7 +1374,8 @@ int startup(char *self, char *cfgFile)
char pidfile[256];
// sprintf(pidfile, "%s/%s.pid",PIDLOCATION, basename(argv[0]));
//sprintf(pidfile, "%s/%s.pid", "/run", basename(argv[0]));
sprintf(pidfile, "%s/%s.pid", "/run", basename(self));
//sprintf(pidfile, "%s/%s.pid", "/run", basename(self));
sprintf(pidfile, "%s/%s.pid", "/run", _aqualink_data.self);
daemonise(pidfile, main_loop);
}
else

View File

@ -497,8 +497,8 @@ int build_aqualink_aqmanager_JSON(struct aqualinkdata *aqdata, char* buffer, int
length += sprintf(buffer+length, ",\"aqualinkd_version\":\"%s\"", AQUALINKD_VERSION ); //1.0b,
*/
//length += sprintf(buffer+length, ",\"logging2file\": \"%s\"",islogFileReady()?JSON_ON:JSON_OFF);
length += sprintf(buffer+length, ",\"logfileready\": \"%s\"",islogFileReady()?JSON_ON:JSON_OFF);
length += sprintf(buffer+length, ",\"logfilename\": \"%s\"",_aqconfig_.log_file);
//length += sprintf(buffer+length, ",\"logfileready\": \"%s\"",islogFileReady()?JSON_ON:JSON_OFF);
//length += sprintf(buffer+length, ",\"logfilename\": \"%s\"",_aqconfig_.log_file);
length += sprintf(buffer+length, ",\"debugmasks\":[");
length += logmaskjsonobject(AQUA_LOG, buffer+length);
length += logmaskjsonobject(NET_LOG, buffer+length);

View File

@ -190,6 +190,7 @@ bool broadcast_systemd_logmessages(bool aqMgrActive) {
char msg[WS_LOG_LENGTH];
static int cnt=0;
static char *cursor = NULL;
char filter[51];
if (!aqMgrActive) {
if (!active) {
@ -208,8 +209,16 @@ bool broadcast_systemd_logmessages(bool aqMgrActive) {
ws_send_logmsg(_mgr.active_connections, msg);
return false;
}
snprintf(filter, 50, "SYSLOG_IDENTIFIER=%s",_aqualink_data->self );
if (sd_journal_add_match(journal, "SYSLOG_IDENTIFIER=aqualinkd", 0) < 0) {
build_logmsg_JSON(msg, LOG_ERR, "Failed to set journal filter", WS_LOG_LENGTH,27);
build_logmsg_JSON(msg, LOG_ERR, "Failed to set journal syslog filter", WS_LOG_LENGTH,35);
ws_send_logmsg(_mgr.active_connections, msg);
sd_journal_close(journal);
return false;
}
snprintf(filter, 50, "_PID=%d",getpid());
if (sd_journal_add_match(journal, filter, 0) < 0) {
build_logmsg_JSON(msg, LOG_ERR, "Failed to set journal PID filter", WS_LOG_LENGTH,32);
ws_send_logmsg(_mgr.active_connections, msg);
sd_journal_close(journal);
return false;
@ -269,6 +278,76 @@ bool broadcast_systemd_logmessages(bool aqMgrActive) {
return true;
}
bool write_systemd_logmessages_2file(char *fname, int lines)
{
FILE *fp = NULL;
sd_journal *journal;
const void *log;
size_t len;
const void *pri;
size_t plen;
char filter[51];
fp = fopen (fname, "w");
if (fp == NULL) {
LOG(NET_LOG, LOG_WARNING, "Failed to open tmp log file '%s'\n",fname);
return false;
}
if (sd_journal_open(&journal, SD_JOURNAL_LOCAL_ONLY) < 0)
{
LOG(NET_LOG, LOG_WARNING, "Failed to open journal");
fclose (fp);
return false;
}
snprintf(filter, 50, "SYSLOG_IDENTIFIER=%s",_aqualink_data->self );
if (sd_journal_add_match(journal, "SYSLOG_IDENTIFIER=aqualinkd", 0) < 0)
{
LOG(NET_LOG, LOG_WARNING, "Failed to set journal syslog filter");
fclose (fp);
sd_journal_close(journal);
return false;
}
snprintf(filter, 50, "_PID=%d",getpid());
if (sd_journal_add_match(journal, filter, 0) < 0)
{
LOG(NET_LOG, LOG_WARNING, "Failed to set journal pid filter");
fclose (fp);
sd_journal_close(journal);
return false;
}
if (sd_journal_seek_tail(journal) < 0)
{
LOG(NET_LOG, LOG_WARNING, "Failed to seek to journal end");
fclose (fp);
sd_journal_close(journal);
return false;
}
if (sd_journal_previous_skip(journal, lines) < 0)
{
LOG(NET_LOG, LOG_WARNING, "Failed to seek to journal start");
fclose (fp);
sd_journal_close(journal);
return false;
}
while ( sd_journal_next(journal) > 0) // need to capture return of this
{
if (sd_journal_get_data(journal, "MESSAGE", &log, &len) < 0) {
LOG(NET_LOG, LOG_WARNING, "Failed to get journal message");
} else if (sd_journal_get_data(journal, "PRIORITY", &pri, &plen) < 0) {
LOG(NET_LOG, LOG_WARNING, "Failed to seek to journal message priority");
} else {
fprintf(fp, "%-7s %.*s\n",elevel2text(atoi((const char *)pri+9)), (int)len-8,(const char *)log+8);
}
}
sd_journal_close(journal);
fclose (fp);
return true;
}
#endif
/* superseded with systemd/sd-journal
@ -813,7 +892,7 @@ void mqtt_broadcast_aqualinkstate(struct mg_connection *nc)
}
typedef enum {uActioned, uBad, uDevices, uStatus, uHomebridge, uDynamicconf, uDebugStatus, uDebugDownload, uSimulator, uSchedules, uSetSchedules, uAQmanager, uNotAvailable} uriAtype;
typedef enum {uActioned, uBad, uDevices, uStatus, uHomebridge, uDynamicconf, uDebugStatus, uDebugDownload, uSimulator, uSchedules, uSetSchedules, uAQmanager, uLogDownload, uNotAvailable} uriAtype;
//typedef enum {NET_MQTT=0, NET_API, NET_WS, DZ_MQTT} netRequest;
const char actionName[][5] = {"MQTT", "API", "WS", "DZ"};
@ -919,14 +998,15 @@ uriAtype action_URI(request_source from, const char *URI, int uri_length, float
removeDebugLogMask(round(value));
return uAQmanager; // Want to resent updated status
} else if (strncmp(ri1, "log2file", 5) == 0) {
/*
if (ri2 != NULL && strncmp(ri2, "start", 5) == 0) {
startInlineLog2File();
} else if (ri2 != NULL && strncmp(ri2, "stop", 4) == 0) {
stopInlineLog2File();
} else if (ri2 != NULL && strncmp(ri2, "clean", 5) == 0) {
cleanInlineLog2File();
} else if (ri2 != NULL && strncmp(ri2, "download", 8) == 0) {
return uDebugDownload;
} else*/ if (ri2 != NULL && strncmp(ri2, "download", 8) == 0) {
return uLogDownload;
}
return uAQmanager; // Want to resent updated status
} else if (strncmp(ri1, "restart", 7) == 0 && from == NET_WS) { // Only valid from websocket.
@ -1403,10 +1483,15 @@ void action_web_request(struct mg_connection *nc, struct http_message *http_msg)
mg_send(nc, message, size);
}
break;
#endif
case uDebugDownload:
mg_http_serve_file(nc, http_msg, getInlineLogFName(), mg_mk_str("text/plain"), mg_mk_str(""));
#else
case uLogDownload:
LOG(NET_LOG, LOG_DEBUG, "Downloading log of max %d lines\n",value>0?(int)value:1000);
if (write_systemd_logmessages_2file("/dev/shm/aqualinkd.log", value>0?(int)value:1000) ) {
mg_http_serve_file(nc, http_msg, "/dev/shm/aqualinkd.log", mg_mk_str("text/plain"), mg_mk_str("Content-Disposition: attachment; filename=\"aqualinkd.log\""));
remove("/dev/shm/aqualinkd.log");
}
break;
#endif
case uBad:
default:
if (msg == NULL) {

View File

@ -279,6 +279,11 @@ bool log_panelversion(struct aqualinkdata *aq_data)
// It's already been set
if (strlen(aq_data->version) > 0) {
// If another protocol set it, we need to check if it's version.
if ( strcmp(aq_data->revision, "0.1") == 0 || strcmp(aq_data->revision, "0.2") == 0 ) {
LOG(ONET_LOG,LOG_NOTICE, "Setting early version for OneTouch\n");
_panel_version_P2 = true;
}
return false;
}

Binary file not shown.

Binary file not shown.

15
utils.c
View File

@ -53,12 +53,15 @@
void broadcast_log(char *msg);
static bool _daemonise = false;
#ifndef AD_MANAGER
static bool _log2file = false;
//static int _log_level = LOG_ERR;
static int _log_level = LOG_WARNING;
static char *_log_filename = NULL;
static bool _cfg_log2file;
static int _cfg_log_level;
#endif
static char *_loq_display_message = NULL;
int16_t _logforcemask = 0;
@ -106,7 +109,7 @@ int getLogLevel(int16_t from)
}
#ifdef AQ_MANAGER
/*
void startInlineLog2File()
{
_log2file = true;
@ -122,6 +125,7 @@ void cleanInlineLog2File() {
fclose(fopen(_log_filename, "w"));
}
}
*/
#else // AQ_MANAGER
void startInlineDebug()
{
@ -149,8 +153,6 @@ void cleanInlineDebug() {
fclose(fopen(_log_filename, "w"));
}
}
#endif // AQ_MANAGER
char *getInlineLogFName()
{
return _log_filename;
@ -166,6 +168,9 @@ bool islogFileReady()
}
return false;
}
#endif // AQ_MANAGER
/*
@ -658,9 +663,9 @@ void daemonise (char *pidFile, void (*main_function) (void))
fp = fopen (pidFile, "w");
if (fp == NULL)
LOG(AQUA_LOG, LOG_ERR,"can't write to PID file %s",pidFile);
LOG(AQUA_LOG, LOG_ERR,"can't write to PID file %s",pidFile);
else
fprintf(fp, "%d", process_id);
fprintf(fp, "%d", process_id);
fclose (fp);
LOG(AQUA_LOG, LOG_DEBUG, "process_id of child process %d \n", process_id);

11
utils.h
View File

@ -102,18 +102,19 @@ char *prittyString(char *str);
#ifdef AQ_MANAGER
void startInlineLog2File();
void stopInlineLog2File();
void cleanInlineLog2File();
//void startInlineLog2File();
//void stopInlineLog2File();
//void cleanInlineLog2File();
#else
void startInlineDebug();
void stopInlineDebug();
void startInlineSerialDebug();
void cleanInlineDebug();
#endif
char *getInlineLogFName();
bool islogFileReady();
#endif
//const char *logmask2name(int16_t from);
//#ifndef _UTILS_C_

View File

@ -263,8 +263,8 @@
document.getElementById("systembutton").dispatchEvent(new Event('click'));
// disable the download log button on startup
disablebutton("downloadlog");
disabletoggle("log2file");
//disablebutton("downloadlog");
//disabletoggle("log2file");
//disabletoggle("seriallog");
}
@ -369,19 +369,35 @@
value: 0
};
} else if (caller.id == "downloadlog") {
//window.location = '/api/debug/download';
downloadFile('/api/debug/download/aqualinkd.log');
downloadFile('/api/log2file/download/aqualinkd.log', document.getElementById("logsize").value);
return;
}
send_command(msg);
}
function downloadFile(filePath) {
var link = document.createElement('a');
link.href = filePath;
link.download = filePath.substr(filePath.lastIndexOf('/') + 1);
link.click();
function downloadFile(filePath, lines) {
console.log("Lines=" + lines);
/*
var link = document.createElement('a');
link.href = filePath;
link.download = filePath.substr(filePath.lastIndexOf('/') + 1);
link.click();
*/
var form = document.createElement('form');
form.setAttribute("style", "display: none;");
form.method='POST';
form.action=filePath;
element=document.createElement('INPUT');
element.name='value';
element.value=lines;
form.appendChild(element);
document.body.appendChild(form);
form.submit();
}
function settoggle(id, onoff) {
@ -453,7 +469,7 @@
enabletoggle("log2file");
else
disabletoggle("log2file");
/*
if (data['logfileready'] == "on") {
enablebutton("downloadlog");
enablebutton("cleanlog");
@ -461,7 +477,7 @@
disablebutton("downloadlog");
disablebutton("cleanlog");
}
*/
var eCommands = document.getElementById("loglevels");
for (var obj in data['loglevels']) {
//console.log(data['loglevels'][obj].name);
@ -617,7 +633,7 @@
disablebutton("restart");
disablebutton("seriallog");
disablebutton("downloadlog");
disabletoggle("log2file");
//disabletoggle("log2file");
var coll = document.getElementsByClassName("collapsible");
var i;
@ -706,12 +722,17 @@
</div>
<button class="collapsible">Log File</button>
<div class="content" id="loglevels">
<!--
<label class="toggle logtoggle"><input class="toggle-checkbox" type="checkbox" id="log2file"
onclick="setlogfile(this);">
<div class="toggle-switch"></div><span class="toggle-label">Log to file</span>
</label>
<input id="downloadlog" type="button" onclick="setlogfile(this);" value="Download logfile"></input>
<input id="cleanlog" type="button" onclick="setlogfile(this);" value="Delete logfile"></input>
-->
<table border='0'><tr><td>
<input id="downloadlog" type="button" onclick="setlogfile(this);" value="Download logfile"></input>
</td><td>
<input id="logsize" type="text" value="1000" size="5">#lines</input>
</td></tr></table>
</div>
<!--&nbsp;-->
<button class="collapsible">Debug Masks</button>