// main log message dispatcher void cSmileLogger::logMsg(int itype, char *s, int level, const char *m) { if (!silence) { // check loglevel and type const char *type=NULL; switch (itype) { case LOG_PRINT : if (level > ll_msg) { free(s); return; } type=NULL; break; case LOG_MESSAGE : if (level > ll_msg) { free(s); return; } type=NULL; break; case LOG_ERROR : if (level > ll_err) { free(s); return; } type="ERROR"; break; case LOG_WARNING : if (level > ll_wrn) { free(s); return; } type="WARN"; break; case LOG_DEBUG : if (level > ll_dbg) { free(s); return; } type="DBG"; break; default: return; } smileMutexLock(logmsgMtx); // format log message if (itype == LOG_PRINT) { if (msg != NULL) { free(msg); msg = NULL; } msg = myvprint("%s",s); if (_enableLogPrint) { // write to file writeMsgToFile(1); } } else { fmtLogMsg(type,s,level,m); // write to file writeMsgToFile(); } free(s); // print to console if ((stde)||(logf == NULL)||(itype==LOG_PRINT)) printMsgToConsole(); smileMutexUnlock(logmsgMtx); } }
static void logfebe_emit_log_hook(ErrorData *edata) { int save_errno; StringInfoData buf; /* * This is one of the few places where we'd rather not inherit a static * variable's value from the postmaster. But since we will, reset it when * MyProcPid changes. */ if (savedPid != MyProcPid) { savedPid = MyProcPid; /* Invalidate all inherited values */ seqNum = 0; cachedBackendStartTime[0] = '\0'; if (outSockFd >= 0) { closeSocket(&outSockFd); } } /* * Increment log sequence number * * Done early on so this happens regardless if there are problems emitting * the log. */ seqNum += 1; /* * Early exit if the socket path is not set and isn't in the format of * an absolute path. * * The empty identity ("ident") is a valid one, so it is not rejected in * the same way an empty logUnixSocketPath is. */ if (logUnixSocketPath == NULL || strlen(logUnixSocketPath) <= 0 || logUnixSocketPath[0] != '/') { /* * Unsetting the GUCs via SIGHUP would leave a connection * dangling, if it exists, close it. */ if (outSockFd >= 0) { closeSocket(&outSockFd); } goto quickExit; } save_errno = errno; /* * Initialize StringInfoDatas early, because pfree is called * unconditionally at exit. */ initStringInfo(&buf); if (outSockFd < 0) { openSocket(&outSockFd, logUnixSocketPath); /* Couldn't get a valid socket; give up */ if (outSockFd < 0) goto exit; } /* * Make room for message type byte and length header. The length header * must be overwritten to the correct value at the end. */ { const char logHdr[5] = {'L', '\0', '\0', '\0', '\0'}; appendBinaryStringInfo(&buf, logHdr, sizeof logHdr); } /* * Format the output, and figure out how long it is, and frame it * for the protocol. */ { uint32_t *msgSize; fmtLogMsg(&buf, edata); /* * Check that buf is prepared properly, with enough space and * the placeholder length expected. */ Assert(buf.len > 5); Assert(buf.data[0] == 'L'); msgSize = (uint32_t *)(buf.data + 1); Assert(*msgSize == 0); /* * Fill in *msgSize: buf contains the msg header, which is not * included in length; subract and byte-swap to paste the * right length into place. */ *msgSize = htobe32(buf.len - 1); } /* Finally: try to send the constructed message */ sendOrInval(&outSockFd, buf.data, buf.len); exit: pfree(buf.data); errno = save_errno; quickExit: /* Call a previous hook, should it exist */ if (prev_emit_log_hook != NULL) prev_emit_log_hook(edata); }