Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhance logging #64

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 51 additions & 8 deletions endlessh.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#define DEFAULT_DELAY 10000 /* milliseconds */
#define DEFAULT_MAX_LINE_LENGTH 32
#define DEFAULT_MAX_CLIENTS 4096
#define DEFAULT_STATS_INTERVAL 60 /* minutes */

#if defined(__FreeBSD__)
# define DEFAULT_CONFIG_FILE "/usr/local/etc/endlessh.config"
Expand Down Expand Up @@ -116,6 +117,7 @@ struct client {
long long connect_time;
long long send_next;
long long bytes_sent;
long send_iter;
struct client *next;
int port;
int fd;
Expand All @@ -130,6 +132,7 @@ client_new(int fd, long long send_next)
c->connect_time = epochms();
c->send_next = send_next;
c->bytes_sent = 0;
c->send_iter = 0;
c->next = 0;
c->fd = fd;
c->port = 0;
Expand Down Expand Up @@ -170,17 +173,18 @@ client_destroy(struct client *client)
long long dt = epochms() - client->connect_time;
logmsg(log_info,
"CLOSE host=%s port=%d fd=%d "
"time=%lld.%03lld bytes=%lld",
"time=%lld.%03lld bytes=%lld iter=%ld",
client->ipaddr, client->port, client->fd,
dt / 1000, dt % 1000,
client->bytes_sent);
client->bytes_sent,
client->send_iter);
statistics.milliseconds += dt;
close(client->fd);
free(client);
}

static void
statistics_log_totals(struct client *clients)
statistics_log_totals(const struct client *clients)
{
long long milliseconds = statistics.milliseconds;
for (long long now = epochms(); clients; clients = clients->next)
Expand Down Expand Up @@ -301,6 +305,7 @@ struct config {
int max_line_length;
int max_clients;
int bind_family;
int stats_interval;
};

#define CONFIG_DEFAULT { \
Expand All @@ -309,6 +314,7 @@ struct config {
.max_line_length = DEFAULT_MAX_LINE_LENGTH, \
.max_clients = DEFAULT_MAX_CLIENTS, \
.bind_family = DEFAULT_BIND_FAMILY, \
.stats_interval = DEFAULT_STATS_INTERVAL, \
}

static void
Expand Down Expand Up @@ -392,6 +398,21 @@ config_set_bind_family(struct config *c, const char *s, int hardfail)
}
}

static void
config_set_stats_interval(struct config *c, const char *s, int hardfail)
{
errno = 0;
char *end;
long tmp = strtol(s, &end, 10);
if (errno || *end || tmp < 0 || tmp > 24 * 60) {
fprintf(stderr, "endlessh: Invalid statistics interval: %s\n", s);
if (hardfail)
exit(EXIT_FAILURE);
} else {
c->stats_interval = tmp;
}
}

enum config_key {
KEY_INVALID,
KEY_PORT,
Expand All @@ -400,6 +421,7 @@ enum config_key {
KEY_MAX_CLIENTS,
KEY_LOG_LEVEL,
KEY_BIND_FAMILY,
KEY_STATS_INTERVAL,
};

static enum config_key
Expand All @@ -411,7 +433,8 @@ config_key_parse(const char *tok)
[KEY_MAX_LINE_LENGTH] = "MaxLineLength",
[KEY_MAX_CLIENTS] = "MaxClients",
[KEY_LOG_LEVEL] = "LogLevel",
[KEY_BIND_FAMILY] = "BindFamily"
[KEY_BIND_FAMILY] = "BindFamily",
[KEY_STATS_INTERVAL] = "StatsInterval"
};
for (size_t i = 1; i < sizeof(table) / sizeof(*table); i++)
if (!strcmp(tok, table[i]))
Expand Down Expand Up @@ -493,6 +516,9 @@ config_load(struct config *c, const char *file, int hardfail)
loglevel = v;
}
} break;
case KEY_STATS_INTERVAL:
config_set_stats_interval(c, tokens[1], hardfail);
break;
}
}

Expand All @@ -511,13 +537,14 @@ config_log(const struct config *c)
c->bind_family == AF_INET6 ? "IPv6 Only" :
c->bind_family == AF_INET ? "IPv4 Only" :
"IPv4 Mapped IPv6");
logmsg(log_info, "StatsInterval %d", c->stats_interval);
}

static void
usage(FILE *f)
{
fprintf(f, "Usage: endlessh [-vh] [-46] [-d MS] [-f CONFIG] [-l LEN] "
"[-m LIMIT] [-p PORT]\n");
"[-m LIMIT] [-p PORT] [-S MIN]\n");
fprintf(f, " -4 Bind to IPv4 only\n");
fprintf(f, " -6 Bind to IPv6 only\n");
fprintf(f, " -d INT Message millisecond delay ["
Expand All @@ -530,6 +557,8 @@ usage(FILE *f)
fprintf(f, " -m INT Maximum number of clients ["
XSTR(DEFAULT_MAX_CLIENTS) "]\n");
fprintf(f, " -p INT Listening port [" XSTR(DEFAULT_PORT) "]\n");
fprintf(f, " -S INT Statistics minute interval ["
XSTR(DEFAULT_STATS_INTERVAL) "]\n");
fprintf(f, " -v Print diagnostics to standard output "
"(repeatable)\n");
fprintf(f, " -V Print version information and exit\n");
Expand Down Expand Up @@ -613,11 +642,14 @@ sendline(struct client *client, int max_line_length, unsigned long *rng)
} else if (errno == EAGAIN || errno == EWOULDBLOCK) {
return client; /* don't care */
} else {
if (errno != EPIPE)
logmsg(log_debug, "errno = %d, %s", errno, strerror(errno));
client_destroy(client);
return 0;
}
} else {
client->bytes_sent += out;
client->send_iter++;
statistics.bytes_sent += out;
return client;
}
Expand All @@ -641,7 +673,7 @@ main(int argc, char **argv)
config_load(&config, config_file, 1);

int option;
while ((option = getopt(argc, argv, "46d:f:hl:m:p:svV")) != -1) {
while ((option = getopt(argc, argv, "46d:f:hl:m:p:sSvV")) != -1) {
switch (option) {
case '4':
config_set_bind_family(&config, "4", 1);
Expand Down Expand Up @@ -679,6 +711,9 @@ main(int argc, char **argv)
case 's':
logmsg = logsyslog;
break;
case 'S':
config_set_stats_interval(&config, optarg, 1);
break;
case 'v':
if (loglevel < log_debug)
loglevel++;
Expand Down Expand Up @@ -735,7 +770,8 @@ main(int argc, char **argv)
struct fifo fifo[1];
fifo_init(fifo);

unsigned long rng = epochms();
long long last_stats_dump = epochms();
unsigned long rng = last_stats_dump;

int server = server_create(config.port, config.bind_family);

Expand All @@ -758,9 +794,16 @@ main(int argc, char **argv)
dumpstats = 0;
}

long long now = epochms();

if (config.stats_interval != 0 && now - last_stats_dump > config.stats_interval * 60 * 1000) {
/* print stats every StatsInterval minutes */
statistics_log_totals(fifo->head);
last_stats_dump = now;
}

/* Enqueue clients that are due for another message */
int timeout = -1;
long long now = epochms();
while (fifo->head) {
if (fifo->head->send_next <= now) {
struct client *c = fifo_pop(fifo);
Expand Down
4 changes: 4 additions & 0 deletions util/smf/endlessh.conf
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,7 @@ LogLevel 1
# 4 = Use IPv4 only
# 6 = Use IPv6 only
BindFamily 0

# Interval in minutes for printing general statistics.
# 0 = Never
StatsInterval 60