elog.c

来自「postgresql8.3.4源码,开源数据库」· C语言 代码 · 共 2,491 行 · 第 1/5 页

C
2,491
字号
				}				break;			case 'c':				appendStringInfo(buf, "%lx.%x", (long) (MyStartTime), MyProcPid);				break;			case 'p':				appendStringInfo(buf, "%d", MyProcPid);				break;			case 'l':				appendStringInfo(buf, "%ld", log_line_number);				break;			case 'm':				{					struct timeval tv;					pg_time_t	stamp_time;					pg_tz	   *tz;					char		msbuf[8];					gettimeofday(&tv, NULL);					stamp_time = (pg_time_t) tv.tv_sec;					/*					 * Normally we print log timestamps in log_timezone, but					 * during startup we could get here before that's set. If					 * so, fall back to gmt_timezone (which guc.c ensures is					 * set up before Log_line_prefix can become nonempty).					 */					tz = log_timezone ? log_timezone : gmt_timezone;					pg_strftime(formatted_log_time, FORMATTED_TS_LEN,					/* leave room for milliseconds... */								"%Y-%m-%d %H:%M:%S     %Z",								pg_localtime(&stamp_time, tz));					/* 'paste' milliseconds into place... */					sprintf(msbuf, ".%03d", (int) (tv.tv_usec / 1000));					strncpy(formatted_log_time + 19, msbuf, 4);					appendStringInfoString(buf, formatted_log_time);				}				break;			case 't':				{					pg_time_t	stamp_time = (pg_time_t) time(NULL);					pg_tz	   *tz;					char		strfbuf[128];					tz = log_timezone ? log_timezone : gmt_timezone;					pg_strftime(strfbuf, sizeof(strfbuf),								"%Y-%m-%d %H:%M:%S %Z",								pg_localtime(&stamp_time, tz));					appendStringInfoString(buf, strfbuf);				}				break;			case 's':				if (formatted_start_time[0] == '\0')				{					pg_time_t	stamp_time = (pg_time_t) MyStartTime;					pg_tz	   *tz;					tz = log_timezone ? log_timezone : gmt_timezone;					pg_strftime(formatted_start_time, FORMATTED_TS_LEN,								"%Y-%m-%d %H:%M:%S %Z",								pg_localtime(&stamp_time, tz));				}				appendStringInfoString(buf, formatted_start_time);				break;			case 'i':				if (MyProcPort)				{					const char *psdisp;					int			displen;					psdisp = get_ps_display(&displen);					appendStringInfo(buf, "%.*s", displen, psdisp);				}				break;			case 'r':				if (MyProcPort && MyProcPort->remote_host)				{					appendStringInfo(buf, "%s", MyProcPort->remote_host);					if (MyProcPort->remote_port &&						MyProcPort->remote_port[0] != '\0')						appendStringInfo(buf, "(%s)",										 MyProcPort->remote_port);				}				break;			case 'h':				if (MyProcPort && MyProcPort->remote_host)					appendStringInfo(buf, "%s", MyProcPort->remote_host);				break;			case 'q':				/* in postmaster and friends, stop if %q is seen */				/* in a backend, just ignore */				if (MyProcPort == NULL)					i = format_len;				break;			case 'v':				/* keep VXID format in sync with lockfuncs.c */				if (MyProc != NULL)					appendStringInfo(buf, "%d/%u",									 MyProc->backendId, MyProc->lxid);				break;			case 'x':				appendStringInfo(buf, "%u", GetTopTransactionIdIfAny());				break;			case '%':				appendStringInfoChar(buf, '%');				break;			default:				/* format error - ignore it */				break;		}	}}/* * append a CSV'd version of a string to a StringInfo * We use the PostgreSQL defaults for CSV, i.e. quote = escape = '"' * If it's NULL, append nothing. */static inline voidappendCSVLiteral(StringInfo buf, const char *data){	const char *p = data;	char		c;	/* avoid confusing an empty string with NULL */	if (p == NULL)		return;	appendStringInfoCharMacro(buf, '"');	while ((c = *p++) != '\0')	{		if (c == '"')			appendStringInfoCharMacro(buf, '"');		appendStringInfoCharMacro(buf, c);	}	appendStringInfoCharMacro(buf, '"');}/* * Constructs the error message, depending on the Errordata it gets, in a CSV * format which is described in doc/src/sgml/config.sgml. */static voidwrite_csvlog(ErrorData *edata){	StringInfoData buf;	bool	print_stmt = false;	/* static counter for line numbers */	static long log_line_number = 0;	/* has counter been reset in current process? */	static int	log_my_pid = 0;	/*	 * 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 (log_my_pid != MyProcPid)	{		log_line_number = 0;		log_my_pid = MyProcPid;		formatted_start_time[0] = '\0';	}	log_line_number++;	initStringInfo(&buf);	/*	 * timestamp with milliseconds	 *	 * Check if the timestamp is already calculated for the syslog message,	 * and use it if so.  Otherwise, get the current timestamp.  This is done	 * to put same timestamp in both syslog and csvlog messages.	 */	if (formatted_log_time[0] == '\0')	{		struct timeval tv;		pg_time_t	stamp_time;		pg_tz	   *tz;		char		msbuf[8];		gettimeofday(&tv, NULL);		stamp_time = (pg_time_t) tv.tv_sec;		/*		 * Normally we print log timestamps in log_timezone, but during		 * startup we could get here before that's set. If so, fall back to		 * gmt_timezone (which guc.c ensures is set up before Log_line_prefix		 * can become nonempty).		 */		tz = log_timezone ? log_timezone : gmt_timezone;		pg_strftime(formatted_log_time, FORMATTED_TS_LEN,		/* leave room for milliseconds... */					"%Y-%m-%d %H:%M:%S     %Z",					pg_localtime(&stamp_time, tz));		/* 'paste' milliseconds into place... */		sprintf(msbuf, ".%03d", (int) (tv.tv_usec / 1000));		strncpy(formatted_log_time + 19, msbuf, 4);	}	appendStringInfoString(&buf, formatted_log_time);	appendStringInfoChar(&buf, ',');	/* username */	if (MyProcPort)		appendCSVLiteral(&buf, MyProcPort->user_name);	appendStringInfoChar(&buf, ',');	/* database name */	if (MyProcPort)		appendCSVLiteral(&buf, MyProcPort->database_name);	appendStringInfoChar(&buf, ',');	/* Process id  */	if (MyProcPid != 0)		appendStringInfo(&buf, "%d", MyProcPid);	appendStringInfoChar(&buf, ',');	/* Remote host and port */	if (MyProcPort && MyProcPort->remote_host)	{		appendStringInfoChar(&buf, '"');		appendStringInfo(&buf, "%s", MyProcPort->remote_host);		if (MyProcPort->remote_port && MyProcPort->remote_port[0] != '\0')			appendStringInfo(&buf, ":%s", MyProcPort->remote_port);		appendStringInfoChar(&buf, '"');	}	appendStringInfoChar(&buf, ',');	/* session id */	appendStringInfo(&buf, "%lx.%x", (long) MyStartTime, MyProcPid);	appendStringInfoChar(&buf, ',');	/* Line number */	appendStringInfo(&buf, "%ld", log_line_number);	appendStringInfoChar(&buf, ',');	/* PS display */	if (MyProcPort)	{		StringInfoData msgbuf;		const char *psdisp;		int			displen;		initStringInfo(&msgbuf);		psdisp = get_ps_display(&displen);		appendStringInfo(&msgbuf, "%.*s", displen, psdisp);		appendCSVLiteral(&buf, msgbuf.data);			pfree(msgbuf.data);	}	appendStringInfoChar(&buf, ',');	/* session start timestamp */	if (formatted_start_time[0] == '\0')	{		pg_time_t	stamp_time = (pg_time_t) MyStartTime;		pg_tz	   *tz = log_timezone ? log_timezone : gmt_timezone;		pg_strftime(formatted_start_time, FORMATTED_TS_LEN,					"%Y-%m-%d %H:%M:%S %Z",					pg_localtime(&stamp_time, tz));	}	appendStringInfoString(&buf, formatted_start_time);	appendStringInfoChar(&buf, ',');	/* Virtual transaction id */	/* keep VXID format in sync with lockfuncs.c */	if (MyProc != NULL && MyProc->backendId != InvalidBackendId)		appendStringInfo(&buf, "%d/%u", MyProc->backendId, MyProc->lxid);	appendStringInfoChar(&buf, ',');	/* Transaction id */	appendStringInfo(&buf, "%u", GetTopTransactionIdIfAny());	appendStringInfoChar(&buf, ',');	/* Error severity */	appendStringInfo(&buf, "%s", error_severity(edata->elevel));	appendStringInfoChar(&buf, ',');	/* SQL state code */	appendStringInfo(&buf, "%s", unpack_sql_state(edata->sqlerrcode));	appendStringInfoChar(&buf, ',');	/* errmessage */	appendCSVLiteral(&buf, edata->message);	appendStringInfoCharMacro(&buf, ',');	/* errdetail */	appendCSVLiteral(&buf, edata->detail);	appendStringInfoCharMacro(&buf, ',');	/* errhint */	appendCSVLiteral(&buf, edata->hint);	appendStringInfoCharMacro(&buf, ',');	/* internal query */	appendCSVLiteral(&buf, edata->internalquery);	appendStringInfoCharMacro(&buf, ',');	/* if printed internal query, print internal pos too */	if (edata->internalpos > 0 && edata->internalquery != NULL)		appendStringInfo(&buf, "%d", edata->internalpos);	appendStringInfoCharMacro(&buf, ',');	/* errcontext */	appendCSVLiteral(&buf, edata->context);	appendStringInfoCharMacro(&buf, ',');	/* user query --- only reported if not disabled by the caller */	if (is_log_level_output(edata->elevel, log_min_error_statement) &&		debug_query_string != NULL &&		!edata->hide_stmt)		print_stmt = true;	if (print_stmt)		appendCSVLiteral(&buf, debug_query_string);	appendStringInfoCharMacro(&buf, ',');	if (print_stmt && edata->cursorpos > 0)		appendStringInfo(&buf, "%d", edata->cursorpos);	appendStringInfoCharMacro(&buf, ',');	/* file error location */	if (Log_error_verbosity >= PGERROR_VERBOSE)	{		StringInfoData	msgbuf;		initStringInfo(&msgbuf);		if (edata->funcname && edata->filename)			appendStringInfo(&msgbuf, "%s, %s:%d",							 edata->funcname, edata->filename,							 edata->lineno);		else if (edata->filename)			appendStringInfo(&msgbuf, "%s:%d",							 edata->filename, edata->lineno);		appendCSVLiteral(&buf, msgbuf.data);		pfree(msgbuf.data);	}	appendStringInfoChar(&buf, '\n');	/* If in the syslogger process, try to write messages direct to file */	if (am_syslogger)		write_syslogger_file(buf.data, buf.len, LOG_DESTINATION_CSVLOG);	else		write_pipe_chunks(buf.data, buf.len, LOG_DESTINATION_CSVLOG);	pfree(buf.data);}/* * Unpack MAKE_SQLSTATE code. Note that this returns a pointer to a * static buffer. */char *unpack_sql_state(int sql_state){	static char buf[12];	int			i;	for (i = 0; i < 5; i++)	{		buf[i] = PGUNSIXBIT(sql_state);		sql_state >>= 6;	}	buf[i] = '\0';	return buf;}/* * Write error report to server's log */static voidsend_message_to_server_log(ErrorData *edata){	StringInfoData buf;	initStringInfo(&buf);	formatted_log_time[0] = '\0';	log_line_prefix(&buf);	appendStringInfo(&buf, "%s:  ", error_severity(edata->elevel));	if (Log_error_verbosity >= PGERROR_VERBOSE)		appendStringInfo(&buf, "%s: ", unpack_sql_state(edata->sqlerrcode));	if (edata->message)		append_with_tabs(&buf, edata->message);	else		append_with_tabs(&buf, _("missing error text"));	if (edata->cursorpos > 0)		appendStringInfo(&buf, _(" at character %d"),						 edata->cursorpos);	else if (edata->internalpos > 0)		appendStringInfo(&buf, _(" at character %d"),						 edata->internalpos);	appendStringInfoChar(&buf, '\n');	if (Log_error_verbosity >= PGERROR_DEFAULT)	{		if (edata->detail)		{			log_line_prefix(&buf);			appendStringInfoString(&buf, _("DETAIL:  "));			append_with_tabs(&buf, edata->detail);			appendStringInfoChar(&buf, '\n');		}		if (edata->hint)		{			log_line_prefix(&buf);			appendStringInfoString(&buf, _("HINT:  "));			append_with_tabs(&buf, edata->hint);			appendStringInfoChar(&buf, '\n');		}		if (edata->internalquery)		{			log_line_prefix(&buf);			appendStringInfoString(&buf, _("QUERY:  "));			append_with_tabs(&buf, edata->internalquery);			appendStringInfoChar(&buf, '\n');		}		if (edata->context)		{			log_line_prefix(&buf);			appendStringInfoString(&buf, _("CONTEXT:  "));			append_with_tabs(&buf, edata->context);			appendStringInfoChar(&buf, '\n');		}		if (Log_error_verbosity >= PGERROR_VERBOSE)		{			/* assume no newlines in funcname or filename... */			if (edata->funcname && edata->filename)			{				log_line_prefix(&buf);				appendStringInfo(&buf, _("LOCATION:  %s, %s:%d\n"),								 edata->funcname, edata->filename,								 edata->lineno);			}			else if (edata->filename)			{				log_line_prefix(&buf);				appendStringInfo(&buf, _("LOCATION:  %s:%d\n"),								 edata->filename, edata->lineno);			}		}	}	/*	 * If the user wants the query that generated this error logged, do it.	 */	if (is_log_level_output(edata->elevel, log_min_error_statement) &&		debug_query_string != NULL &&		!edata->hide_stmt)	{		log_line_prefix(&buf);		appendStringInfoString(&buf, _("STATEMENT:  "));		append_with_tabs(&buf, debug_query_string);		appendStringInfoChar(&buf, '\n');	}#ifdef HAVE_SYSLOG	/* Write to syslog, if enabled */	if (Log_destination & LOG_DESTINATION_SYSLOG)	{		int			syslog_level;		switch (edata->elevel)		{			case DEBUG5:			case DEBUG4:			case DEBUG3:			case DEBUG2:			case DEBUG1:				syslog_level = LOG_DEBUG;				break;			case LOG:			case COMMERROR:			case INFO:				syslog_level = LOG_INFO;				break;			case NOTICE:			case WARNING:				syslog_level = LOG_NOTICE;				break;			case ERROR:

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?