Пример #1
0
void log_init(int restart)
{
	if (log_initialised) {
		if (!restart)
			return;
		if (strcmp(logfile_name, lp_log_file(module_id)) != 0) {
			if (logfile_fp) {
				fclose(logfile_fp);
				logfile_fp = NULL;
			} else
				closelog();
			logfile_name = NULL;
		} else if (*logfile_name)
			return; /* unchanged, non-empty "log file" names */
		else if (lp_syslog_facility(-1) != lp_syslog_facility(module_id))
			closelog();
		else
			return; /* unchanged syslog settings */
	} else
		log_initialised = 1;

	/* This looks pointless, but it is needed in order for the
	 * C library on some systems to fetch the timezone info
	 * before the chroot. */
	timestring(time(NULL));

	/* Optionally use a log file instead of syslog.  (Non-daemon
	 * rsyncs will have already set logfile_name, as needed.) */
	if (am_daemon && !logfile_name)
		logfile_name = lp_log_file(module_id);
	if (logfile_name && *logfile_name)
		logfile_open();
	else
		syslog_init();
}
Пример #2
0
void logfile_reopen(void)
{
	if (logfile_was_closed) {
		logfile_was_closed = 0;
		logfile_open();
	}
}
Пример #3
0
static void logfile_param_changed(cvar_t *self)
{
    if (logfile_enable->integer) {
        logfile_close();
        logfile_open();
    }
}
Пример #4
0
static void logfile_enable_changed(cvar_t *self)
{
    logfile_close();
    if (self->integer) {
        logfile_open();
    }
}
Пример #5
0
int server_init(server_t *server)
{
    assert(server!= NULL);

	pthread_mutex_init(&server->send_pending_lock, NULL);
	pthread_cond_init(&server->send_pending_cond, NULL);

    UNUSED int r;

    get_instance_parent_full_path(server->root_dir, NAME_MAX);

    sprintf(server->storage.storage_dir, "%s/data/storage", server->root_dir);
    if ( mkdir_if_not_exist(server->storage.storage_dir) != 0 ){
        error_log("mkdir %s failed.", server->storage.storage_dir);
        return -1;
    }

    char log_dir[NAME_MAX];
    sprintf(log_dir, "%s/data/log", server->root_dir);
    if ( mkdir_if_not_exist(log_dir) != 0 ) {
        error_log("mkdir %s failed.", log_dir);
        return -1;
    }

    /*r = storage_init(&server->storage);*/
    int i;
    for ( i = 0 ; i < VNODES ; i++ ){
        vnode_t *vnode = vnode_new(server->storage.storage_dir, i);
        if ( vnode == NULL ){
            error_log("vnode_init() failed. id:%d", i);
            return -1;
        }
        server->vnodes[i] = vnode;
    }

    /* logfile */
    for ( i = 0 ; i < LOGFILES ; i++ ) {
        char logfile_name[NAME_MAX];
        sprintf(logfile_name, "%s/%02d.log", log_dir, i);

        logfile_t *logfile = logfile_new(i, logfile_name);

        if ( logfile_open(logfile, 1) != 0 ) {
            error_log("logfile_open(%d) failed.", i);
            return -1;
        }

        server->logfiles[i] = logfile;
    }

    /* FIXME */
    r = init_server_work_queue(server);
    if ( r != 0 ){
        error_log("init_server_work_queue() failed.");
        return -1;
    }

    return 0;
}
Пример #6
0
/*
 * open the csv log file - we do this opportunistically, because
 * we don't know if CSV logging will be wanted.
 */
static void
open_cvs_logfile(void)
{
	char* filename;

	filename = logfile_getname(time(NULL), ".csv");
	cvs_logfile = logfile_open(filename, "a", false);
	pfree(filename);
}
Пример #7
0
bool logfile_stat(const char *fname)
{
  struct stat st;
  int fd = open(fname, O_RDONLY);

  if (fd == -1 || fstat(fd, &st) < 0) {
    if (fd != -1)
      close(fd);
    fclose(logf);
    logf = NULL;
    if (!logfile_open())
      return 0;
  }
  return 1;
}
Пример #8
0
//set last
int				logger_write(logger_t * logger, int loglv, const char* fmt, ...)
{
	if (logger == nullptr){
		logger = G_LOGGER;
	}
	if (loglv < logger->conf.lv){
		return 0;
	}
    logger_lock(logger);
	va_list ap;
	va_start(ap, fmt);
	int n = 0;
	logger->last_err = errno;
	char * msg_start = (char*)logger->last_msg.data();
	n = vsnprintf(msg_start, logger->last_msg.capacity() - 1, fmt, ap);
	va_end(ap);
	int available_size = logger->last_msg.capacity() - (n + 2);
	char errorno_msg_buff[128];
	if (loglv >= LOG_LVL_WARNING && available_size > 16){
		if (msg_start[n-1] == '\n'){
			--n;
		}
		snprintf(&msg_start[n], available_size, " [system errno:%d(%s)]\n", errno,
			strerror_r(errno, errorno_msg_buff, sizeof(errorno_msg_buff)-1));
	}
	if (logger->pf){
		fputs(msg_start, logger->pf);
		if (ftell(logger->pf) >= logger->conf.max_file_size){
			//shift file <>
			fflush(logger->pf);
			fclose(logger->pf);
			string nextfile = logger->logfile + "." + std::to_string(logger->next_rollid);
			rename(logger->logfile.c_str(), nextfile.c_str());
			int nextrollid = (logger->next_rollid + 1) % logger->conf.max_roll;
			if (nextrollid == 0) nextrollid = 3;
			if ((logger->pf = logfile_open(logger->logfile.c_str(), nextrollid))){
				logger->next_rollid = nextrollid;
			}
		}
	}
	else{
		fputs(logger->last_msg.c_str(), stderr);
	}
    logger_unlock(logger);
	return n;
}
Пример #9
0
logger_t *	logger_create(const logger_config_t & conf){
	FILE * pf = nullptr;
	int	 nextrollid = 0;
	string filepath = conf.dir + "/" + conf.pattern;
	if (filepath.length() > 1){
		pf = logfile_open(filepath.c_str(), nextrollid);
	}
	logger_t * em = new logger_t();
	if (!em) return nullptr;
	em->last_msg.reserve(conf.max_msg_size);
	em->conf = conf;
	em->inited = true;
	em->next_rollid = nextrollid;
	em->logfile = filepath;
	em->pf = pf;

	return em;
}
Пример #10
0
void logfile(int type, const char *msg)
{
  if (!logf && !logfile_open())
    return;

  if (!logfile_stat(".l"))
    return;

  if (!egg_strncasecmp(msg, log_last, sizeof(log_last))) {
    repeats++;
    return;
  }
  if (repeats) {
    fprintf(logf, "Last message repeated %d times.\n", repeats);
    repeats = 0;
  }

  strlcpy(log_last, msg, sizeof(log_last));

  fprintf(logf, "%s\n", msg);
  if (flush_log)
    fflush(logf);
}
Пример #11
0
/*
 * Postmaster subroutine to start a syslogger subprocess.
 */
int
SysLogger_Start(void)
{
	pid_t		sysloggerPid;
	char	   *filename;

	if (!Logging_collector)
		return 0;

	/*
	 * If first time through, create the pipe which will receive stderr
	 * output.
	 *
	 * If the syslogger crashes and needs to be restarted, we continue to use
	 * the same pipe (indeed must do so, since extant backends will be writing
	 * into that pipe).
	 *
	 * This means the postmaster must continue to hold the read end of the
	 * pipe open, so we can pass it down to the reincarnated syslogger. This
	 * is a bit klugy but we have little choice.
	 */
#ifndef WIN32
	if (syslogPipe[0] < 0)
	{
		if (pipe(syslogPipe) < 0)
			ereport(FATAL,
					(errcode_for_socket_access(),
					 (errmsg("could not create pipe for syslog: %m"))));
	}
#else
	if (!syslogPipe[0])
	{
		SECURITY_ATTRIBUTES sa;

		memset(&sa, 0, sizeof(SECURITY_ATTRIBUTES));
		sa.nLength = sizeof(SECURITY_ATTRIBUTES);
		sa.bInheritHandle = TRUE;

		if (!CreatePipe(&syslogPipe[0], &syslogPipe[1], &sa, 32768))
			ereport(FATAL,
					(errcode_for_file_access(),
					 (errmsg("could not create pipe for syslog: %m"))));
	}
#endif

	/*
	 * Create log directory if not present; ignore errors
	 */
	mkdir(Log_directory, S_IRWXU);

	/*
	 * The initial logfile is created right in the postmaster, to verify that
	 * the Log_directory is writable.  We save the reference time so that the
	 * syslogger child process can recompute this file name.
	 *
	 * It might look a bit strange to re-do this during a syslogger restart,
	 * but we must do so since the postmaster closed syslogFile after the
	 * previous fork (and remembering that old file wouldn't be right anyway).
	 * Note we always append here, we won't overwrite any existing file.  This
	 * is consistent with the normal rules, because by definition this is not
	 * a time-based rotation.
	 */
	first_syslogger_file_time = time(NULL);
	filename = logfile_getname(first_syslogger_file_time, NULL);

	syslogFile = logfile_open(filename, "a", false);

	pfree(filename);

#ifdef EXEC_BACKEND
	switch ((sysloggerPid = syslogger_forkexec()))
#else
	switch ((sysloggerPid = fork_process()))
#endif
	{
		case -1:
			ereport(LOG,
					(errmsg("could not fork system logger: %m")));
			return 0;

#ifndef EXEC_BACKEND
		case 0:
			/* in postmaster child ... */
			/* Close the postmaster's sockets */
			ClosePostmasterPorts(true);

			/* Lose the postmaster's on-exit routines */
			on_exit_reset();

			/* Drop our connection to postmaster's shared memory, as well */
			PGSharedMemoryDetach();

			/* do the work */
			SysLoggerMain(0, NULL);
			break;
#endif

		default:
			/* success, in postmaster */

			/* now we redirect stderr, if not done already */
			if (!redirection_done)
			{
#ifndef WIN32
				fflush(stdout);
				if (dup2(syslogPipe[1], fileno(stdout)) < 0)
					ereport(FATAL,
							(errcode_for_file_access(),
							 errmsg("could not redirect stdout: %m")));
				fflush(stderr);
				if (dup2(syslogPipe[1], fileno(stderr)) < 0)
					ereport(FATAL,
							(errcode_for_file_access(),
							 errmsg("could not redirect stderr: %m")));
				/* Now we are done with the write end of the pipe. */
				close(syslogPipe[1]);
				syslogPipe[1] = -1;
#else
				int			fd;

				/*
				 * open the pipe in binary mode and make sure stderr is binary
				 * after it's been dup'ed into, to avoid disturbing the pipe
				 * chunking protocol.
				 */
				fflush(stderr);
				fd = _open_osfhandle((intptr_t) syslogPipe[1],
									 _O_APPEND | _O_BINARY);
				if (dup2(fd, _fileno(stderr)) < 0)
					ereport(FATAL,
							(errcode_for_file_access(),
							 errmsg("could not redirect stderr: %m")));
				close(fd);
				_setmode(_fileno(stderr), _O_BINARY);

				/*
				 * Now we are done with the write end of the pipe.
				 * CloseHandle() must not be called because the preceding
				 * close() closes the underlying handle.
				 */
				syslogPipe[1] = 0;
#endif
				redirection_done = true;
			}

			/* postmaster will never write the file; close it */
			fclose(syslogFile);
			syslogFile = NULL;
			return (int) sysloggerPid;
	}

	/* we should never reach here */
	return 0;
}
Пример #12
0
/*
 * Postmaster subroutine to start a syslogger subprocess.
 */
int
syslog_start(void)
{
	pid_t pid;
	char *filename;

	if (!log_collector)
		return 0;

	/*
	 * If first time through, create the pipe which will receive stderr
	 * output. If syslog crashes and needs to be restarted, we continue to 
	 * use the same pipe. Indeed must do so, since extant backends will be
	 * writing into that pipe.
	 *
	 * This means the postmaster must continue to hold the read end of the
	 * pipe open, so we can pass it down to the reincarnated syslogger. This
	 * is a bit klugy but we have little choice.
	 */
#ifndef WIN32
	if (syslog_pipe[0] < 0) {
		if (pgpipe(syslog_pipe) < 0)
			ereport(FATAL, (
			errcode_sock_access(),
			errmsg("could not create pipe for syslog: %m")));
	}
#else
	if (!syslog_pipe[0]) {
		SECURITY_ATTRIBUTES sa;

		memset(&sa, 0, sizeof(SECURITY_ATTRIBUTES));
		sa.nLength = sizeof(SECURITY_ATTRIBUTES);
		sa.bInheritHandle = TRUE;

		if (!CreatePipe(&syslog_pipe[0], &syslog_pipe[1], &sa, 32768))
			ereport(FATAL, (
			errcode_file_access(),
			errmsg("could not create pipe for syslog: %m")));
	}
#endif

	/*
	 * Create log directory if not present; ignore errors
	 */
	mkdir(log_directory, S_IRWXU);

	/*
	 * The initial logfile is created right in the postmaster, to verify i
	 * that the log_directory is writable.
	 */
	filename = logfile_getname(time(NULL), NULL);
	syslog_file = logfile_open(filename, "a", false);
	pfree(filename);

#ifdef EXEC_BACKEND
	switch ((pid = syslog_forkexec())) {
#else
	switch ((pid = fork_process())) {
#endif
	case -1:
		ereport(LOG, (errmsg("could not fork system logger: %m")));
		return 0;

#ifndef EXEC_BACKEND
	case 0:
		/* in postmaster child ... */
		/* Close the postmaster's sockets */
		close_ports(true);

		/* Lose the postmaster's on-exit routines */
		on_exit_reset();

		/* Drop our connection to postmaster's shared memory */
		shm_child_detach();

		/* do the work */
		syslog_main(0, NULL);
		break;
#endif

	default:
		/* success, in postmaster */

		/* now we redirect stderr, if not done already */
		if (!redirection_done) {
#ifndef WIN32
			fflush(stdout);
			if (dup2(syslog_pipe[1], fileno(stdout)) < 0) {
				ereport(FATAL, (
				errcode_file_access(),
				errmsg("could not redirect stdout: %m")));
			}

			fflush(stderr);
			if (dup2(syslog_pipe[1], fileno(stderr)) < 0) {
				ereport(FATAL, (
				errcode_file_access(),
				errmsg("could not redirect stderr: %m")));
			}

			/* Now we are done with the write end of pipe */
			close(syslog_pipe[1]);
			syslog_pipe[1] = -1;
#else
			int fd;

			/*
			 * open the pipe in binary mode and make sure stderr is binary
			 * after it's been dup'ed into, to avoid disturbing the pipe
			 * chunking protocol.
			 */
			fflush(stderr);
			fd = _open_osfhandle((intptr_t) syslog_pipe[1], _O_APPEND | _O_BINARY);
			if (dup2(fd, _fileno(stderr)) < 0)
				ereport(FATAL, (
				errcode_file_access(),
				errmsg("could not redirect stderr: %m")));

			close(fd);
			_setmode(_fileno(stderr), _O_BINARY);

			/* Now we are done with the write end of the pipe. */
			CloseHandle(syslog_pipe[1]);
			syslog_pipe[1] = 0;
#endif
			redirection_done = true;
		}

		/* postmaster will never write the file; close it */
		fclose(syslog_file);
		syslog_file = NULL;
		return (int) pid;
	}

	/* we should never reach here */
	return 0;
}


#ifdef EXEC_BACKEND

/*
 * syslog_forkexec() -
 *
 * Format up the arglist for, then fork and exec, a syslogger process
 */
static pid_t
syslog_forkexec(void)
{
	char *av[10];
	int ac = 0;
	char filenobuf[32];

	av[ac++] = "postgres";
	av[ac++] = "--forklog";
	av[ac++] = NULL;			/* filled in by master_forkexec */

	/* static variables (those not passed by write_backend_variables) */
#ifndef WIN32
	if (syslog_file != NULL)
		snprintf(filenobuf, sizeof(filenobuf), "%d", fileno(syslog_file));
	else
		strcpy(filenobuf, "-1");

#else	/* WIN32 */
	if (syslog_file != NULL)
		snprintf(filenobuf, sizeof(filenobuf), "%ld",
			(long) _get_osfhandle(_fileno(syslog_file)));
	else
		strcpy(filenobuf, "0");

#endif   /* WIN32 */
	av[ac++] = filenobuf;
	av[ac] = NULL;
	ASSERT(ac < lengthof(av));

	return master_forkexec(ac, av);
}
Пример #13
0
/*
 * perform logfile rotation
 */
static void
logfile_rotate(bool time_based_rotation, int size_rotation_for)
{
	char* filename;
	char* csv_filename = NULL;
	pg_time_t fntime;
	FILE* fh;

	rotation_requested = false;

	/*
	 * When doing a time-based rotation, invent the new logfile name based on
	 * the planned rotation time, not current time, to avoid "slippage" in the
	 * file name when we don't do the rotation immediately.
	 */
	if (time_based_rotation)
		fntime = next_rotation_time;
	else
		fntime = time(NULL);

	filename = logfile_getname(fntime, NULL);
	if (cvs_logfile != NULL)
		csv_filename = logfile_getname(fntime, ".csv");

	/*
	 * Decide whether to overwrite or append.  We can overwrite if (a)
	 * log_truncate_on_rotation is set, (b) the rotation was triggered by
	 * elapsed time and not something else, and (c) the computed file name is
	 * different from what we were previously logging into.
	 *
	 * Note: during the first rotation after forking off from the postmaster,
	 * last_file_name will be NULL.  (We don't bother to set it in the
	 * postmaster because it ain't gonna work in the EXEC_BACKEND case.) So we
	 * will always append in that situation, even though truncating would
	 * usually be safe.
	 *
	 * For consistency, we treat CSV logs the same even though they aren't
	 * opened in the postmaster.
	 */
	if (time_based_rotation || (size_rotation_for & DEST_STDERR)) {
		if (log_truncate_on_rotation
			&& time_based_rotation
			&& last_file_name != NULL
			&& strcmp(filename, last_file_name) != 0)
			fh = logfile_open(filename, "w", true);
		else
			fh = logfile_open(filename, "a", true);

		if (!fh) {
			/*
			 * ENFILE/EMFILE are not too surprising on a busy system; just
			 * keep using the old file till we manage to get a new one.
			 * Otherwise, assume something's wrong with log_directory and stop
			 * trying to create files.
			 */
			if (errno != ENFILE && errno != EMFILE) {
				ereport(LOG, (
				errmsg("disabling automatic rotation (use SIGHUP to re-enable)")));
				log_rotation_age = 0;
				log_rotation_size = 0;
			}

			if (filename)
				pfree(filename);

			if (csv_filename)
				pfree(csv_filename);

			return;
		}

		fclose(syslog_file);
		syslog_file = fh;

		/* instead of pfree'ing filename, remember it for next time */
		if (last_file_name != NULL)
			pfree(last_file_name);

		last_file_name = filename;
		filename = NULL;
	}

	/* Same as above, but for csv file. */
	if (cvs_logfile != NULL
		&& (time_based_rotation || (size_rotation_for & DEST_CSVLOG))) {
		if (log_truncate_on_rotation
			&& time_based_rotation
			&& last_csv_file_name != NULL
			&& strcmp(csv_filename, last_csv_file_name) != 0)
			fh = logfile_open(csv_filename, "w", true);
		else
			fh = logfile_open(csv_filename, "a", true);

		if (!fh) {
			/*
			 * ENFILE/EMFILE are not too surprising on a busy system; just
			 * keep using the old file till we manage to get a new one.
			 * Otherwise, assume something's wrong with log_directory and stop
			 * trying to create files.
			 */
			if (errno != ENFILE && errno != EMFILE) {
				ereport(LOG, (
				errmsg("disabling automatic rotation (use SIGHUP to re-enable)")));
				log_rotation_age = 0;
				log_rotation_size = 0;
			}

			if (filename)
				pfree(filename);

			if (csv_filename)
				pfree(csv_filename);

			return;
		}

		fclose(cvs_logfile);
		cvs_logfile = fh;

		/* instead of pfree'ing filename, remember it for next time */
		if (last_csv_file_name != NULL)
			pfree(last_csv_file_name);

		last_csv_file_name = csv_filename;
		csv_filename = NULL;
	}

	if (filename)
		pfree(filename);

	if (csv_filename)
		pfree(csv_filename);

	set_next_rotation_time();
}