示例#1
0
ret_t
cherokee_logger_writer_flush (cherokee_logger_writer_t *writer,
                              cherokee_boolean_t        locked)
{
	int   re;
	ret_t ret = ret_ok;

	/* The internal buffer might be empty
	 */
	if (cherokee_buffer_is_empty (&writer->buffer)) {
		return ret_ok;
	}

	if (!locked) {
		CHEROKEE_MUTEX_LOCK (&PRIV(writer)->mutex);
	}

	/* If not, do the proper thing
	 */
	switch (writer->type) {
	case cherokee_logger_writer_stderr:
		/* In this case we ignore errors.
		 */
		re = fwrite (writer->buffer.buf, 1, writer->buffer.len, stderr);
		if (re != (size_t) writer->buffer.len) {
			ret = ret_error;
		}

		/* Cleanup the log buffer even if there is an error,
		 * because it's safer to go on anyway.
		 */
		cherokee_buffer_clean (&writer->buffer);
		break;

	case cherokee_logger_writer_pipe:
	case cherokee_logger_writer_file:
	{
		ssize_t nwr = 0;
		size_t  buflen = writer->buffer.len;

		/* If there is at least 1 page to write then round
		 * down the length to speed up write(s).
		 */
		if (buflen > LOGGER_BUF_PAGESIZE) {
			buflen &= ~LOGGER_BUF_PAGESIZE;
		}

		do {
			nwr = write (writer->fd, writer->buffer.buf, buflen);
		} while (nwr == -1 && errno == EINTR);

		if (nwr <= 0) {
			/* If an error occured in blocking write, then
			 * cleanup the log buffer now because we don't
			 * want to let it grow too much.
			 */
			cherokee_buffer_clean (&writer->buffer);
			ret = ret_error;
			goto out;
		}

		/* OK, something has been written.
		 */
		cherokee_buffer_move_to_begin (&writer->buffer, nwr);
		if (! cherokee_buffer_is_empty (&writer->buffer)) {
			ret = ret_eagain;
		}
		break;
	}
	case cherokee_logger_writer_syslog:
		/* Write to syslog the whole log buffer, then cleanup
		 * it in any case.
		 */
		ret = cherokee_syslog (LOG_INFO, &writer->buffer);
		cherokee_buffer_clean (&writer->buffer);
		break;

	default:
		SHOULDNT_HAPPEN;
		ret = ret_error;
	}

out:
	if (! locked) {
		CHEROKEE_MUTEX_UNLOCK (&PRIV(writer)->mutex);
	}
	return ret;
}
示例#2
0
文件: trace.c 项目: BeQ/webserver
void
cherokee_trace_do_trace (const char *entry, const char *file, int line, const char *func, const char *fmt, ...)
{
	ret_t                  ret;
	char                  *p;
	char                  *lentry;
	char                  *lentry_end;
	va_list                args;
	cherokee_connection_t *conn;
	cherokee_buffer_t     *trace_modules = &trace.modules;
	cherokee_boolean_t     do_log        = false;
	cherokee_buffer_t      entries       = CHEROKEE_BUF_INIT;

	/* Prevents loops
	 */
	if (disabled) {
		return;
	}

	disabled = true;

	/* Return ASAP if nothing is being traced
	 */
	if (cherokee_buffer_is_empty (&trace.modules)) {
		goto out;
	}

	/* Check the connection source, if possible
	 */
	if (trace.from_filter != NULL) {
		conn = CONN (CHEROKEE_THREAD_PROP_GET (thread_connection_ptr));

		/* No conn, no trace entry
		 */
		if (conn == NULL) {
			goto out;
		}

		if (conn->socket.socket < 0) {
			goto out;
		}

		/* Skip the trace if the conn doesn't match
		 */
		ret = cherokee_access_ip_match (trace.from_filter, &conn->socket);
		if (ret != ret_ok) {
			goto out;
		}
	}

	/* Also, check for 'all'
	 */
	p = strstr (trace_modules->buf, "all");
	if (p == NULL) {
		/* Parse the In-code module string
		 */
		cherokee_buffer_add (&entries, entry, strlen(entry));

		for (lentry = entries.buf;;) {
			lentry_end = strchr (lentry, ',');
			if (lentry_end) *lentry_end = '\0';

			/* Check the type
			 */
			p = strstr (trace_modules->buf, lentry);
			if (p) {
				char *tmp = p + strlen(lentry);
				if ((*tmp == '\0') || (*tmp == ',') || (*tmp == ' '))
					do_log = true;
			}

			if ((lentry_end == NULL) || (do_log))
				break;

			lentry = lentry_end + 1;
		}

		/* Return if trace entry didn't match with the configured list
		 */
		if (! do_log) {
			goto out;
		}
	}

	/* Format the message and log it:
	 * 'entries' is not needed at this stage, reuse it
	 */
	cherokee_buffer_clean (&entries);
	if (trace.print_thread) {
		int        len;
		char       tmp[32+1];
		static int longest_len = 0;

		len = snprintf (tmp, 32+1, "%llX", (unsigned long long) CHEROKEE_THREAD_SELF);
		longest_len = MAX (longest_len, len);

		cherokee_buffer_add_str    (&entries, "{0x");
		cherokee_buffer_add_char_n (&entries, '0', longest_len - len);
		cherokee_buffer_add        (&entries, tmp, len);
		cherokee_buffer_add_str    (&entries, "} ");
	}

	if (trace.print_time) {
		cherokee_buffer_add_char (&entries, '[');
		cherokee_buf_add_bogonow (&entries, true);
		cherokee_buffer_add_str  (&entries, "] ");
	}

	cherokee_buffer_add_va (&entries, "%18s:%04d (%30s): ", file, line, func);

	va_start (args, fmt);
	cherokee_buffer_add_va_list (&entries, (char *)fmt, args);
	va_end (args);

	if (trace.use_syslog) {
		cherokee_syslog (LOG_DEBUG, &entries);
	} else {
#ifdef HAVE_FLOCKFILE
		flockfile (stdout);
#endif
		fprintf (stdout, "%s", entries.buf);
#ifdef HAVE_FUNLOCKFILE
		funlockfile (stdout);
#endif
	}

out:
	cherokee_buffer_mrproper (&entries);
	disabled = false;
}