Add new net command for text logging
authorJens Axboe <axboe@kernel.dk>
Sat, 3 Mar 2012 19:28:07 +0000 (20:28 +0100)
committerJens Axboe <axboe@kernel.dk>
Sat, 3 Mar 2012 19:28:07 +0000 (20:28 +0100)
Encapsulate the text in a payload, that also includes the
logging level and the time the event took place. The text
client will do as it always has done, but the gui client
can now do proper logging and knows if this is debug/info
or error messages.

No functional change in the GUI.

Signed-off-by: Jens Axboe <axboe@kernel.dk>
client.c
client.h
gfio.c
log.c
log.h
server.c
server.h

index feb1eba52440eb5a3bda9f53cef6f64e3ff2df1e..ff3983bdf84c37e727ce5b481fe0574fddeff7f5 100644 (file)
--- a/client.c
+++ b/client.c
 #include "flist.h"
 #include "hash.h"
 
-static void fio_client_text_op(struct fio_client *client,
-               FILE *f, __u16 pdu_len, const char *buf)
-{
-       const char *name;
-       int fio_unused ret;
-
-       name = client->name ? client->name : client->hostname;
-
-       if (!client->skip_newline)
-               fprintf(f, "<%s> ", name);
-       ret = fwrite(buf, pdu_len, 1, f);
-       fflush(f);
-       client->skip_newline = strchr(buf, '\n') == NULL;
-}
-
 static void handle_du(struct fio_client *client, struct fio_net_cmd *cmd);
 static void handle_ts(struct fio_net_cmd *cmd);
 static void handle_gs(struct fio_net_cmd *cmd);
 static void handle_eta(struct fio_client *client, struct fio_net_cmd *cmd);
 static void handle_probe(struct fio_client *client, struct fio_net_cmd *cmd);
+static void handle_text(struct fio_client *client, struct fio_net_cmd *cmd);
 
 struct client_ops fio_client_ops = {
-       .text_op        = fio_client_text_op,
+       .text_op        = handle_text,
        .disk_util      = handle_du,
        .thread_status  = handle_ts,
        .group_stats    = handle_gs,
@@ -698,6 +684,23 @@ static void convert_dus(struct disk_util_stat *dus)
        dus->msec               = le64_to_cpu(dus->msec);
 }
 
+static void handle_text(struct fio_client *client, struct fio_net_cmd *cmd)
+{
+       struct cmd_text_pdu *pdu = (struct cmd_text_pdu *) cmd->payload;
+       const char *buf = (const char *) pdu->buf;
+       const char *name;
+       int fio_unused ret;
+
+       name = client->name ? client->name : client->hostname;
+
+       if (!client->skip_newline)
+               fprintf(f_out, "<%s> ", name);
+       ret = fwrite(buf, pdu->buf_len, 1, f_out);
+       fflush(f_out);
+       client->skip_newline = strchr(buf, '\n') == NULL;
+}
+
+
 static void handle_du(struct fio_client *client, struct fio_net_cmd *cmd)
 {
        struct cmd_du_pdu *du = (struct cmd_du_pdu *) cmd->payload;
@@ -851,6 +854,16 @@ static void handle_stop(struct fio_client *client, struct fio_net_cmd *cmd)
                log_info("client <%s>: exited with error %d\n", client->hostname, client->error);
 }
 
+static void convert_text(struct fio_net_cmd *cmd)
+{
+       struct cmd_text_pdu *pdu = (struct cmd_text_pdu *) cmd->payload;
+
+       pdu->level      = le32_to_cpu(pdu->level);
+       pdu->buf_len    = le32_to_cpu(pdu->buf_len);
+       pdu->log_sec    = le64_to_cpu(pdu->log_sec);
+       pdu->log_usec   = le64_to_cpu(pdu->log_usec);
+}
+
 int fio_handle_client(struct fio_client *client, struct client_ops *ops)
 {
        struct fio_net_cmd *cmd;
@@ -871,12 +884,11 @@ int fio_handle_client(struct fio_client *client, struct client_ops *ops)
                remove_client(client);
                free(cmd);
                break;
-       case FIO_NET_CMD_TEXT: {
-               const char *buf = (const char *) cmd->payload;
-               ops->text_op(client, f_out, cmd->pdu_len, buf);
+       case FIO_NET_CMD_TEXT:
+               convert_text(cmd);
+               ops->text_op(client, cmd);
                free(cmd);
                break;
-               }
        case FIO_NET_CMD_DU:
                ops->disk_util(client, cmd);
                free(cmd);
index de6c19711d9516b60d948c0d371d24be7d4ff2b1..7ab4c83a3c814a78cdd118e5d9d915b85c8510f5 100644 (file)
--- a/client.h
+++ b/client.h
@@ -46,8 +46,7 @@ struct fio_client {
        void *client_data;
 };
 
-typedef void (*client_text_op_func)(struct fio_client *client,
-               FILE *f, __u16 pdu_len, const char *buf);
+typedef void (*client_text_op_func)(struct fio_client *client, struct fio_net_cmd *cmd);
 typedef void (*client_disk_util_op_func)(struct fio_client *client, struct fio_net_cmd *cmd);
 typedef void (*client_thread_status_op)(struct fio_net_cmd *cmd);
 typedef void (*client_group_stats_op)(struct fio_net_cmd *cmd);
diff --git a/gfio.c b/gfio.c
index 34b21ab917ad348243b6f329e1872c6fcfaa49cb..32e012e7ba360535157a97f856fe5ec7b0117249 100644 (file)
--- a/gfio.c
+++ b/gfio.c
@@ -130,8 +130,7 @@ static void gfio_set_connected(struct gui *ui, int connected)
        }
 }
 
-static void gfio_text_op(struct fio_client *client,
-                FILE *f, __u16 pdu_len, const char *buf)
+static void gfio_text_op(struct fio_client *client, struct fio_net_cmd *cmd)
 {
 #if 0
        GtkTextBuffer *buffer;
@@ -145,7 +144,7 @@ static void gfio_text_op(struct fio_client *client,
        gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW(ui.textview),
                                        &end, 0.0, FALSE, 0.0,0.0);
 #else
-       fio_client_ops.text_op(client, f, pdu_len, buf);
+       fio_client_ops.text_op(client, cmd);
 #endif
 }
 
diff --git a/log.c b/log.c
index af974f85b594abc1951b4bfb77ad625f4887b529..362ab23c9813b9366c78ff55b4de8ffdd013a631 100644 (file)
--- a/log.c
+++ b/log.c
@@ -60,7 +60,7 @@ int log_info(const char *format, ...)
        va_end(args);
 
        if (is_backend)
-               return fio_server_text_output(buffer, len);
+               return fio_server_text_output(FIO_LOG_INFO, buffer, len);
        else if (log_syslog) {
                syslog(LOG_INFO, "%s", buffer);
                return len;
@@ -79,7 +79,7 @@ int log_err(const char *format, ...)
        va_end(args);
 
        if (is_backend)
-               return fio_server_text_output(buffer, len);
+               return fio_server_text_output(FIO_LOG_ERR, buffer, len);
        else if (log_syslog) {
                syslog(LOG_INFO, "%s", buffer);
                return len;
diff --git a/log.h b/log.h
index fdf3d7b19aed3d3981b166c32339fbd7bb596f79..2b2cae0c74ee1aa975d5d91cf966c657ce0cc2d7 100644 (file)
--- a/log.h
+++ b/log.h
@@ -13,4 +13,10 @@ extern int log_local(const char *format, ...);
 extern int log_valist(const char *str, va_list);
 extern int log_local_buf(const char *buf, size_t);
 
+enum {
+       FIO_LOG_DEBUG   = 1,
+       FIO_LOG_INFO    = 2,
+       FIO_LOG_ERR     = 3,
+};
+
 #endif
index 299c3e1a22a57cc4f4f10aac367bf0aad8e24fff..1e2fcd06c4b323bf99aa040b9feccfbe7b44ec76 100644 (file)
--- a/server.c
+++ b/server.c
@@ -222,12 +222,19 @@ struct fio_net_cmd *fio_net_recv_cmd(int sk)
                cmdret = NULL;
        } else if (cmdret) {
                /* zero-terminate text input */
-               if (cmdret->pdu_len && (cmdret->opcode == FIO_NET_CMD_TEXT ||
-                   cmdret->opcode == FIO_NET_CMD_JOB)) {
-                       char *buf = (char *) cmdret->payload;
+               if (cmdret->pdu_len) {
+                       if (cmdret->opcode == FIO_NET_CMD_TEXT) {
+                               struct cmd_text_pdu *pdu = (struct cmd_text_pdu *) cmdret->payload;
+                               char *buf = (char *) pdu->buf;
 
-                       buf[cmdret->pdu_len ] = '\0';
+                               buf[pdu->buf_len ] = '\0';
+                       } else if (cmdret->opcode == FIO_NET_CMD_JOB) {
+                               char *buf = (char *) cmdret->payload;
+
+                               buf[cmdret->pdu_len ] = '\0';
+                       }
                }
+
                /* frag flag is internal */
                cmdret->flags &= ~FIO_NET_CMD_F_MORE;
        }
@@ -619,12 +626,30 @@ out:
        return exitval;
 }
 
-int fio_server_text_output(const char *buf, size_t len)
+int fio_server_text_output(int level, const char *buf, size_t len)
 {
-       if (server_fd != -1)
-               return fio_net_send_cmd(server_fd, FIO_NET_CMD_TEXT, buf, len, 0);
+       struct cmd_text_pdu *pdu;
+       unsigned int tlen;
+       struct timeval tv;
+
+       if (server_fd == -1)
+               return log_local_buf(buf, len);
+
+       tlen = sizeof(*pdu) + len;
+       pdu = malloc(tlen);
+
+       pdu->level      = __cpu_to_le32(level);
+       pdu->buf_len    = __cpu_to_le32(len);
+
+       gettimeofday(&tv, NULL);
+       pdu->log_sec    = __cpu_to_le64(tv.tv_sec);
+       pdu->log_usec   = __cpu_to_le64(tv.tv_usec);
 
-       return log_local_buf(buf, len);
+       memcpy(pdu->buf, buf, len);
+
+       fio_net_send_cmd(server_fd, FIO_NET_CMD_TEXT, pdu, tlen, 0);
+       free(pdu);
+       return len;
 }
 
 static void convert_io_stat(struct io_stat *dst, struct io_stat *src)
@@ -826,21 +851,6 @@ void fio_server_send_add_job(struct thread_options *o, const char *ioengine)
        fio_net_send_cmd(server_fd, FIO_NET_CMD_ADD_JOB, &pdu, sizeof(pdu), 0);
 }
 
-int fio_server_log(const char *format, ...)
-{
-       char buffer[1024];
-       va_list args;
-       size_t len;
-
-       dprint(FD_NET, "server log\n");
-
-       va_start(args, format);
-       len = vsnprintf(buffer, sizeof(buffer), format, args);
-       va_end(args);
-
-       return fio_server_text_output(buffer, len);
-}
-
 static int fio_init_server_ip(void)
 {
        struct sockaddr *addr;
index 5c7c8db9fcbb006b0414453d69085e37e34ed150..299c7a03738b002e318ef4d7df2e8886cfe23fac 100644 (file)
--- a/server.h
+++ b/server.h
@@ -38,7 +38,7 @@ struct fio_net_int_cmd {
 };
 
 enum {
-       FIO_SERVER_VER          = 8,
+       FIO_SERVER_VER          = 9,
 
        FIO_SERVER_MAX_PDU      = 1024,
 
@@ -118,9 +118,16 @@ struct cmd_add_job_pdu {
        uint32_t group_reporting;
 };
 
+struct cmd_text_pdu {
+       uint32_t level;
+       uint32_t buf_len;
+       uint64_t log_sec;
+       uint64_t log_usec;
+       uint8_t buf[0];
+};
+
 extern int fio_start_server(char *);
-extern int fio_server_text_output(const char *, size_t);
-extern int fio_server_log(const char *format, ...);
+extern int fio_server_text_output(int, const char *, size_t);
 extern int fio_net_send_cmd(int, uint16_t, const void *, off_t, uint64_t);
 extern int fio_net_send_simple_cmd(int, uint16_t, uint64_t, struct flist_head *);
 extern void fio_server_set_arg(const char *);