<commit_before>/* $Id$ */

/*
 * Logging routines.
 * Notes:
 *	(o) We cannot use psc_fatal() for fatal errors here.  Instead use err(3).
 */

#define PSC_SUBSYS PSS_LOG

#include <sys/param.h>
#include <sys/time.h>
#include <sys/syscall.h>

#include <ctype.h>
#include <err.h>
#include <errno.h>
#include <pthread.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include "psc_util/alloc.h"
#include "psc_util/cdefs.h"
#include "psc_util/fmtstr.h"
#include "psc_util/lock.h"
#include "psc_util/log.h"

#ifndef PSC_LOG_FMT
#define PSC_LOG_FMT "[%s:%06u %n:%F:%l]"
#endif

struct fuse_context {
	uid_t uid;
	gid_t gid;
	pid_t pid;
};

__static const char		*psc_logfmt = PSC_LOG_FMT;
__static int			 psc_loglevel = PLL_TRACE;
__static struct psclog_data	*psc_logdata;

void
psc_log_init(void)
{
	char *ep, *p;
	long l;

	if ((p = getenv("PSC_LOG_FORMAT")) != NULL)
		psc_logfmt = p;
	if ((p = getenv("PSC_LOG_LEVEL")) != NULL) {
		ep = NULL;
		errno = 0;
		l = strtol(p, &ep, 10);
		if (p[0] == '\0' || ep == NULL || *ep != '\0')
			errx(1, "invalid log level env: %s", p);
		if (errno == ERANGE || l < 0 || l >= PNLOGLEVELS)
			errx(1, "invalid log level env: %s", p);
		psc_loglevel = (int)l;
	}
}

__weak struct psclog_data *
psclog_getdatamem(void)
{
	return (psc_logdata);
}

__weak void
psclog_setdatamem(struct psclog_data *d)
{
	psc_logdata = d;
}

int
psc_log_getlevel_global(void)
{
	return (psc_loglevel);
}

__weak int
psc_log_getlevel_ss(__unusedx int subsys)
{
	return (psc_log_getlevel_global());
}

__weak int
psc_log_getlevel(int subsys)
{
	return (psc_log_getlevel_ss(subsys));
}

void
psc_log_setlevel_global(int newlevel)
{
	if (newlevel >= PNLOGLEVELS || newlevel < 0)
		errx(1, "log level out of bounds (%d)", newlevel);
	psc_loglevel = newlevel;
}

__weak void
psc_log_setlevel_ss(__unusedx int subsys, int newlevel)
{
	psc_log_setlevel_global(newlevel);
}

__weak void
psc_log_setlevel(int subsys, int newlevel)
{
	psc_log_setlevel_ss(subsys, newlevel);
}

__weak const char *
pscthr_getname(void)
{
	return (NULL);
}

__weak int
MPI_Comm_rank(__unusedx int comm, int *rank)
{
	*rank = -1;
	return (0);
}

__weak struct fuse_context *
psclog_get_fuse_context(void)
{
	return (NULL);
}

struct psclog_data *
psclog_getdata(void)
{
	struct psclog_data *d;
	char *p;

	d = psclog_getdatamem();
	if (d == NULL) {
		d = PSCALLOC(sizeof(*d));
		if (gethostname(d->pld_hostname,
		    sizeof(d->pld_hostname)) == -1)
			err(1, "gethostname");
		if ((p = strchr(d->pld_hostname, '.')) != NULL)
			*p = '\0';
#ifdef LINUX
		MPI_Comm_rank(1, &d->pld_rank); /* 1=MPI_COMM_WORLD */
#else
	        d->pld_rank = cnos_get_rank();
#endif
		psclog_setdatamem(d);
	}
	return (d);
}

void
psclogv(const char *fn, const char *func, int line, int subsys,
    int level, int options, const char *fmt, va_list ap)
{
	char prefix[LINE_MAX], emsg[LINE_MAX], umsg[LINE_MAX];
	struct fuse_context *ctx;
	struct psclog_data *d;
	struct timeval tv;
	const char *thrname;
	int save_errno;

	save_errno = errno;

	d = psclog_getdata();
	thrname = pscthr_getname();
	if (thrname == NULL) {
		if (d->pld_nothrname[0] == '\0')
			snprintf(d->pld_nothrname,
			    sizeof(d->pld_nothrname),
			    "<%ld>", syscall(SYS_gettid));
		thrname = d->pld_nothrname;
	}

	ctx = psclog_get_fuse_context();

	gettimeofday(&tv, NULL);
	FMTSTR(prefix, sizeof(prefix), psc_logfmt,
		FMTSTRCASE('F', prefix, sizeof(prefix), "s", func)
		FMTSTRCASE('f', prefix, sizeof(prefix), "s", fn)
		FMTSTRCASE('h', prefix, sizeof(prefix), "s", d->pld_hostname)
		FMTSTRCASE('i', prefix, sizeof(prefix), "ld", syscall(SYS_gettid))
		FMTSTRCASE('L', prefix, sizeof(prefix), "d", level)
		FMTSTRCASE('l', prefix, sizeof(prefix), "d", line)
		FMTSTRCASE('n', prefix, sizeof(prefix), "s", thrname)
		FMTSTRCASE('P', prefix, sizeof(prefix), "d", ctx ? (int)ctx->pid : -1)
		FMTSTRCASE('r', prefix, sizeof(prefix), "d", d->pld_rank)
		FMTSTRCASE('s', prefix, sizeof(prefix), "lu", tv.tv_sec)
		FMTSTRCASE('t', prefix, sizeof(prefix), "d", subsys)<commit_msg>simplify the fuse_context hackery<commit_after>/* $Id$ */

/*
 * Logging routines.
 * Notes:
 *	(o) We cannot use psc_fatal() for fatal errors here.  Instead use err(3).
 */

#define PSC_SUBSYS PSS_LOG

#include <sys/param.h>
#include <sys/time.h>
#include <sys/syscall.h>

#include <ctype.h>
#include <err.h>
#include <errno.h>
#include <pthread.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include "psc_util/alloc.h"
#include "psc_util/cdefs.h"
#include "psc_util/fmtstr.h"
#include "psc_util/lock.h"
#include "psc_util/log.h"

#ifndef PSC_LOG_FMT
#define PSC_LOG_FMT "[%s:%06u %n:%F:%l]"
#endif

struct fuse_context {
	uid_t uid;
	gid_t gid;
	pid_t pid;
};

__static const char		*psc_logfmt = PSC_LOG_FMT;
__static int			 psc_loglevel = PLL_TRACE;
__static struct psclog_data	*psc_logdata;

void
psc_log_init(void)
{
	char *ep, *p;
	long l;

	if ((p = getenv("PSC_LOG_FORMAT")) != NULL)
		psc_logfmt = p;
	if ((p = getenv("PSC_LOG_LEVEL")) != NULL) {
		ep = NULL;
		errno = 0;
		l = strtol(p, &ep, 10);
		if (p[0] == '\0' || ep == NULL || *ep != '\0')
			errx(1, "invalid log level env: %s", p);
		if (errno == ERANGE || l < 0 || l >= PNLOGLEVELS)
			errx(1, "invalid log level env: %s", p);
		psc_loglevel = (int)l;
	}
}

__weak struct psclog_data *
psclog_getdatamem(void)
{
	return (psc_logdata);
}

__weak void
psclog_setdatamem(struct psclog_data *d)
{
	psc_logdata = d;
}

int
psc_log_getlevel_global(void)
{
	return (psc_loglevel);
}

__weak int
psc_log_getlevel_ss(__unusedx int subsys)
{
	return (psc_log_getlevel_global());
}

__weak int
psc_log_getlevel(int subsys)
{
	return (psc_log_getlevel_ss(subsys));
}

void
psc_log_setlevel_global(int newlevel)
{
	if (newlevel >= PNLOGLEVELS || newlevel < 0)
		errx(1, "log level out of bounds (%d)", newlevel);
	psc_loglevel = newlevel;
}

__weak void
psc_log_setlevel_ss(__unusedx int subsys, int newlevel)
{
	psc_log_setlevel_global(newlevel);
}

__weak void
psc_log_setlevel(int subsys, int newlevel)
{
	psc_log_setlevel_ss(subsys, newlevel);
}

__weak const char *
pscthr_getname(void)
{
	return (NULL);
}

/**
 * MPI_Comm_rank - dummy overrideable MPI rank retriever.
 */
__weak int
MPI_Comm_rank(__unusedx int comm, int *rank)
{
	*rank = -1;
	return (0);
}

/**
 * fuse_get_context - dummy overrideable fuse context retriever.
 */
__weak struct fuse_context *
fuse_get_context(void)
{
	return (NULL);
}

struct psclog_data *
psclog_getdata(void)
{
	struct psclog_data *d;
	char *p;

	d = psclog_getdatamem();
	if (d == NULL) {
		d = PSCALLOC(sizeof(*d));
		if (gethostname(d->pld_hostname,
		    sizeof(d->pld_hostname)) == -1)
			err(1, "gethostname");
		if ((p = strchr(d->pld_hostname, '.')) != NULL)
			*p = '\0';
#ifdef LINUX
		MPI_Comm_rank(1, &d->pld_rank); /* 1=MPI_COMM_WORLD */
#else
	        d->pld_rank = cnos_get_rank();
#endif
		psclog_setdatamem(d);
	}
	return (d);
}

void
psclogv(const char *fn, const char *func, int line, int subsys,
    int level, int options, const char *fmt, va_list ap)
{
	char prefix[LINE_MAX], emsg[LINE_MAX], umsg[LINE_MAX];
	struct fuse_context *ctx;
	struct psclog_data *d;
	struct timeval tv;
	const char *thrname;
	int save_errno;

	save_errno = errno;

	d = psclog_getdata();
	thrname = pscthr_getname();
	if (thrname == NULL) {
		if (d->pld_nothrname[0] == '\0')
			snprintf(d->pld_nothrname,
			    sizeof(d->pld_nothrname),
			    "<%ld>", syscall(SYS_gettid));
		thrname = d->pld_nothrname;
	}

	ctx = fuse_get_context();

	gettimeofday(&tv, NULL);
	FMTSTR(prefix, sizeof(prefix), psc_logfmt,
		FMTSTRCASE('F', prefix, sizeof(prefix), "s", func)
		FMTSTRCASE('f', prefix, sizeof(prefix), "s", fn)
		FMTSTRCASE('h', prefix, sizeof(prefix), "s", d->pld_hostname)
		FMTSTRCASE('i', prefix, sizeof(prefix), "ld", syscall(SYS_gettid))
		FMTSTRCASE('L', prefix, sizeof(prefix), "d", level)
		FMTSTRCASE('l', prefix, sizeof(prefix), "d", line)
		FMTSTRCASE('n', prefix, sizeof(prefix), "s", thrname)
		FMTSTRCASE('P', prefix, sizeof(prefix), "d", ctx ? (int)ctx->pid : -1)
		FMTSTRCASE('r', prefix, sizeof(prefix), "d", d->pld_rank)
		FMTSTRCASE('s', prefix, sizeof(prefix), "lu", tv.tv_sec)
		FMTSTRCASE('t', prefix, sizeof(prefix), "d", subsys)
{'fraction_non_alphanumeric': 0.16495592319768143, 'fraction_numerical': 0.0057964014007970055, 'mean_word_length': 4.711724137931035, 'pattern_counts': {'":': 0, '<': 33, '<?xml version=': 0, '>': 57, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5500946', 'n_tokens_mistral': 3708, 'n_tokens_neox': 3585, 'n_words': 782}