⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 elog.c

📁 PostgreSQL 8.1.4的源码 适用于Linux下的开源数据库系统
💻 C
📖 第 1 页 / 共 4 页
字号:
	}	buf[i] = '\0';	return buf;}/* * Write error report to server's log */static voidsend_message_to_server_log(ErrorData *edata){	StringInfoData buf;	initStringInfo(&buf);	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 (edata->elevel >= log_min_error_statement && debug_query_string != NULL)	{		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:				syslog_level = LOG_WARNING;				break;			case FATAL:				syslog_level = LOG_ERR;				break;			case PANIC:			default:				syslog_level = LOG_CRIT;				break;		}		write_syslog(syslog_level, buf.data);	}#endif   /* HAVE_SYSLOG */#ifdef WIN32	/* Write to eventlog, if enabled */	if (Log_destination & LOG_DESTINATION_EVENTLOG)	{		write_eventlog(edata->elevel, buf.data);	}#endif   /* WIN32 */	/* Write to stderr, if enabled */	if ((Log_destination & LOG_DESTINATION_STDERR) || whereToSendOutput == DestDebug)	{#ifdef WIN32		/*		 * In a win32 service environment, there is no usable stderr. Capture		 * anything going there and write it to the eventlog instead.		 *		 * If stderr redirection is active, it's ok to write to stderr because		 * that's really a pipe to the syslogger process.		 */		if ((!Redirect_stderr || am_syslogger) && pgwin32_is_service())			write_eventlog(edata->elevel, buf.data);		else#endif			fprintf(stderr, "%s", buf.data);	}	/* If in the syslogger process, try to write messages direct to file */	if (am_syslogger)		write_syslogger_file(buf.data, buf.len);	pfree(buf.data);}/* * Write error report to client */static voidsend_message_to_frontend(ErrorData *edata){	StringInfoData msgbuf;	/* 'N' (Notice) is for nonfatal conditions, 'E' is for errors */	pq_beginmessage(&msgbuf, (edata->elevel < ERROR) ? 'N' : 'E');	if (PG_PROTOCOL_MAJOR(FrontendProtocol) >= 3)	{		/* New style with separate fields */		char		tbuf[12];		int			ssval;		int			i;		pq_sendbyte(&msgbuf, PG_DIAG_SEVERITY);		pq_sendstring(&msgbuf, error_severity(edata->elevel));		/* unpack MAKE_SQLSTATE code */		ssval = edata->sqlerrcode;		for (i = 0; i < 5; i++)		{			tbuf[i] = PGUNSIXBIT(ssval);			ssval >>= 6;		}		tbuf[i] = '\0';		pq_sendbyte(&msgbuf, PG_DIAG_SQLSTATE);		pq_sendstring(&msgbuf, tbuf);		/* M field is required per protocol, so always send something */		pq_sendbyte(&msgbuf, PG_DIAG_MESSAGE_PRIMARY);		if (edata->message)			pq_sendstring(&msgbuf, edata->message);		else			pq_sendstring(&msgbuf, _("missing error text"));		if (edata->detail)		{			pq_sendbyte(&msgbuf, PG_DIAG_MESSAGE_DETAIL);			pq_sendstring(&msgbuf, edata->detail);		}		if (edata->hint)		{			pq_sendbyte(&msgbuf, PG_DIAG_MESSAGE_HINT);			pq_sendstring(&msgbuf, edata->hint);		}		if (edata->context)		{			pq_sendbyte(&msgbuf, PG_DIAG_CONTEXT);			pq_sendstring(&msgbuf, edata->context);		}		if (edata->cursorpos > 0)		{			snprintf(tbuf, sizeof(tbuf), "%d", edata->cursorpos);			pq_sendbyte(&msgbuf, PG_DIAG_STATEMENT_POSITION);			pq_sendstring(&msgbuf, tbuf);		}		if (edata->internalpos > 0)		{			snprintf(tbuf, sizeof(tbuf), "%d", edata->internalpos);			pq_sendbyte(&msgbuf, PG_DIAG_INTERNAL_POSITION);			pq_sendstring(&msgbuf, tbuf);		}		if (edata->internalquery)		{			pq_sendbyte(&msgbuf, PG_DIAG_INTERNAL_QUERY);			pq_sendstring(&msgbuf, edata->internalquery);		}		if (edata->filename)		{			pq_sendbyte(&msgbuf, PG_DIAG_SOURCE_FILE);			pq_sendstring(&msgbuf, edata->filename);		}		if (edata->lineno > 0)		{			snprintf(tbuf, sizeof(tbuf), "%d", edata->lineno);			pq_sendbyte(&msgbuf, PG_DIAG_SOURCE_LINE);			pq_sendstring(&msgbuf, tbuf);		}		if (edata->funcname)		{			pq_sendbyte(&msgbuf, PG_DIAG_SOURCE_FUNCTION);			pq_sendstring(&msgbuf, edata->funcname);		}		pq_sendbyte(&msgbuf, '\0');		/* terminator */	}	else	{		/* Old style --- gin up a backwards-compatible message */		StringInfoData buf;		initStringInfo(&buf);		appendStringInfo(&buf, "%s:  ", error_severity(edata->elevel));		if (edata->show_funcname && edata->funcname)			appendStringInfo(&buf, "%s: ", edata->funcname);		if (edata->message)			appendStringInfoString(&buf, edata->message);		else			appendStringInfoString(&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');		pq_sendstring(&msgbuf, buf.data);		pfree(buf.data);	}	pq_endmessage(&msgbuf);	/*	 * This flush is normally not necessary, since postgres.c will flush out	 * waiting data when control returns to the main loop. But it seems best	 * to leave it here, so that the client has some clue what happened if the	 * backend dies before getting back to the main loop ... error/notice	 * messages should not be a performance-critical path anyway, so an extra	 * flush won't hurt much ...	 */	pq_flush();}/* * Support routines for formatting error messages. *//* * expand_fmt_string --- process special format codes in a format string * * We must replace %m with the appropriate strerror string, since vsnprintf * won't know what to do with it. * * The result is a palloc'd string. */static char *expand_fmt_string(const char *fmt, ErrorData *edata){	StringInfoData buf;	const char *cp;	initStringInfo(&buf);	for (cp = fmt; *cp; cp++)	{		if (cp[0] == '%' && cp[1] != '\0')		{			cp++;			if (*cp == 'm')			{				/*				 * Replace %m by system error string.  If there are any %'s in				 * the string, we'd better double them so that vsnprintf won't				 * misinterpret.				 */				const char *cp2;				cp2 = useful_strerror(edata->saved_errno);				for (; *cp2; cp2++)				{					if (*cp2 == '%')						appendStringInfoCharMacro(&buf, '%');					appendStringInfoCharMacro(&buf, *cp2);				}			}			else			{				/* copy % and next char --- this avoids trouble with %%m */				appendStringInfoCharMacro(&buf, '%');				appendStringInfoCharMacro(&buf, *cp);			}		}		else			appendStringInfoCharMacro(&buf, *cp);	}	return buf.data;}/* * A slightly cleaned-up version of strerror() */static const char *useful_strerror(int errnum){	/* this buffer is only used if errno has a bogus value */	static char errorstr_buf[48];	const char *str;#ifdef WIN32	/* Winsock error code range, per WinError.h */	if (errnum >= 10000 && errnum <= 11999)		return pgwin32_socket_strerror(errnum);#endif	str = strerror(errnum);	/*	 * Some strerror()s return an empty string for out-of-range errno. This is	 * ANSI C spec compliant, but not exactly useful.	 */	if (str == NULL || *str == '\0')	{		/*		 * translator: This string will be truncated at 47 characters		 * expanded.		 */		snprintf(errorstr_buf, sizeof(errorstr_buf),				 _("operating system error %d"), errnum);		str = errorstr_buf;	}	return str;}/* * error_severity --- get localized string representing elevel */static const char *error_severity(int elevel){	const char *prefix;	switch (elevel)	{		case DEBUG1:		case DEBUG2:		case DEBUG3:		case DEBUG4:		case DEBUG5:			prefix = _("DEBUG");			break;		case LOG:		case COMMERROR:			prefix = _("LOG");			break;		case INFO:			prefix = _("INFO");			break;		case NOTICE:			prefix = _("NOTICE");			break;		case WARNING:			prefix = _("WARNING");			break;		case ERROR:			prefix = _("ERROR");			break;		case FATAL:			prefix = _("FATAL");			break;		case PANIC:			prefix = _("PANIC");			break;		default:			prefix = "???";			break;	}	return prefix;}/* *	append_with_tabs * *	Append the string to the StringInfo buffer, inserting a tab after any *	newline. */static voidappend_with_tabs(StringInfo buf, const char *str){	char		ch;	while ((ch = *str++) != '\0')	{		appendStringInfoCharMacro(buf, ch);		if (ch == '\n')			appendStringInfoCharMacro(buf, '\t');	}}/* * Write errors to stderr (or by equal means when stderr is * not available). Used before ereport/elog can be used * safely (memory context, GUC load etc) */voidwrite_stderr(const char *fmt,...){	va_list		ap;	fmt = _(fmt);	va_start(ap, fmt);#ifndef WIN32	/* On Unix, we just fprintf to stderr */	vfprintf(stderr, fmt, ap);#else	/*	 * On Win32, we print to stderr if running on a console, or write to	 * eventlog if running as a service	 */	if (pgwin32_is_service())	/* Running as a service */	{		char		errbuf[2048];		/* Arbitrary size? */		vsnprintf(errbuf, sizeof(errbuf), fmt, ap);		write_eventlog(EVENTLOG_ERROR_TYPE, errbuf);	}	else		/* Not running as service, write to stderr */		vfprintf(stderr, fmt, ap);#endif	va_end(ap);}

⌨️ 快捷键说明

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