Exemplo n.º 1
0
// 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);
  }
}
Exemplo n.º 2
0
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);
}