On Sat, Oct 19, 2013 at 11:35:33PM +0900, Hitoshi Mitake wrote:
> This patch adds two new opcode for runtime loglevel changes and let
> dog support the changing from command line. This is useful for making
> sheep process verbose temporally and can make troubleshooting easier.
> 
> Example of usage:
> 
> $ dog node loglevel list
> emerg   (0)
> alert   (1)
> crit    (2)
> err     (3)
> warning (4)
> notice  (5)
> info    (6)
> debug   (7)
> $ dog node loglevel get
> info (6)
> $ dog node loglevel set debug # <- change loglevel from info to debug
> $ dog node loglevel get
> debug (7)
> 
> Signed-off-by: Hitoshi Mitake <mitake.hito...@lab.ntt.co.jp>
> ---
>  CHANGELOG.md             |  8 +++--
>  dog/common.c             | 84 
> ++++++++++++++++++++++++++++++++++++++++++++++++
>  dog/dog.h                |  5 +++
>  dog/node.c               | 79 ++++++++++++++++++++++++++++++++++++++++++++-
>  include/internal_proto.h |  2 ++
>  include/logger.h         |  3 ++
>  lib/logger.c             | 12 +++++++
>  sheep/ops.c              | 43 +++++++++++++++++++++++++
>  8 files changed, 233 insertions(+), 3 deletions(-)
> 
> diff --git a/CHANGELOG.md b/CHANGELOG.md
> index 98d221e..771d69b 100644
> --- a/CHANGELOG.md
> +++ b/CHANGELOG.md
> @@ -3,9 +3,13 @@
>  
>  DOG COMMAND INTERFACE:
>   - new subcommand "vdi cache purge" for cleaning stale object cache
> - -- "vdi cache purge" cleans stale cache of all images
> - -- "vdi cache purge <image>" cleans stale cache of the specified image
> +  - "vdi cache purge" cleans stale cache of all images
> +  - "vdi cache purge <image>" cleans stale cache of the specified image
>   - new subcommand "node stat" for showing I/O status of the node
> + - new subcommand "node loglevel" for changing log level at runtime
> +  - "node loglevel set" sets loglevel of running sheep process
> +  - "node loglevel get" gets loglevel from running sheep process
> +  - "node loglevel list" lists avialable loglevels
>  
>  SHEEP COMMAND INTERFACE:
>   - improvements of help messages
> diff --git a/dog/common.c b/dog/common.c
> index 5e7ce2e..44e116d 100644
> --- a/dog/common.c
> +++ b/dog/common.c
> @@ -351,3 +351,87 @@ bool is_erasure_oid(uint64_t oid, uint8_t policy)
>               return false;
>       return true;
>  }
> +
> +static const char *loglevel_table[] = {
> +     "emerg",
> +     "alert",
> +     "crit",
> +     "err",
> +     "warning",
> +     "notice",
> +     "info",
> +     "debug",
> +};                           /* index is log level */
> +
> +int do_loglevel_set(const struct node_id *nid, const char *loglevel_str)
> +{
> +     int32_t loglevel = -1;
> +     int ret;
> +     struct sd_req hdr;
> +     struct sd_rsp *rsp = (struct sd_rsp *)&hdr;
> +
> +     for (int i = 0; i < ARRAY_SIZE(loglevel_table); i++) {
> +             if (!strcmp(loglevel_table[i], loglevel_str)) {
> +                     loglevel = i;
> +                     break;
> +             }
> +     }
> +
> +     if (loglevel == -1)
> +             return EXIT_USAGE;
> +
> +     sd_init_req(&hdr, SD_OP_SET_LOGLEVEL);
> +     hdr.flags = SD_FLAG_CMD_WRITE;
> +     hdr.data_length = sizeof(loglevel);
> +
> +     ret = dog_exec_req(nid, &hdr, &loglevel);
> +     if (ret < 0)
> +             return EXIT_SYSFAIL;
> +
> +     if (rsp->result != SD_RES_SUCCESS)
> +             return EXIT_FAILURE;
> +
> +     return EXIT_SUCCESS;
> +}
> +
> +int do_loglevel_get(const struct node_id *nid, int32_t *ret_loglevel)
> +{
> +     int32_t loglevel = -1;
> +     int ret;
> +     struct sd_req hdr;
> +     struct sd_rsp *rsp = (struct sd_rsp *)&hdr;
> +
> +     sd_init_req(&hdr, SD_OP_GET_LOGLEVEL);
> +     hdr.data_length = sizeof(loglevel);
> +
> +     ret = dog_exec_req(nid, &hdr, &loglevel);
> +     if (ret < 0)
> +             return EXIT_SYSFAIL;
> +
> +     if (rsp->result != SD_RES_SUCCESS)
> +             return EXIT_FAILURE;
> +
> +     *ret_loglevel = loglevel;
> +
> +     return EXIT_SUCCESS;
> +}
> +
> +const char *loglevel_to_str(int loglevel)
> +{
> +     for (int i = 0; i < ARRAY_SIZE(loglevel_table); i++) {
> +             if (i == loglevel)
> +                     return loglevel_table[i];
> +     }
> +
> +     return "unknown loglevel";
> +}
> +
> +void dump_loglevels(bool err)
> +{
> +     for (int i = 0; i < ARRAY_SIZE(loglevel_table); i++) {
> +             if (err)
> +                     sd_err("%s\t(%d)", loglevel_table[i], i);
> +             else
> +                     sd_info("%s\t(%d)", loglevel_table[i], i);
> +     }
> +}
> diff --git a/dog/dog.h b/dog/dog.h
> index 769fc6c..28c36a1 100644
> --- a/dog/dog.h
> +++ b/dog/dog.h
> @@ -95,4 +95,9 @@ extern struct command cluster_command;
>    #define trace_command {}
>  #endif /* HAVE_TRACE */
>  
> +int do_loglevel_set(const struct node_id *nid, const char *loglevel_str);
> +int do_loglevel_get(const struct node_id *nid, int32_t *ret_loglevel);
> +const char *loglevel_to_str(int loglevel);
> +void dump_loglevels(bool err);
> +
>  #endif
> diff --git a/dog/node.c b/dog/node.c
> index 052739c..5f1b070 100644
> --- a/dog/node.c
> +++ b/dog/node.c
> @@ -420,7 +420,6 @@ static int node_md(int argc, char **argv)
>       return do_generic_subcommand(node_md_cmd, argc, argv);
>  }
>  
> -
>  static int node_parser(int ch, const char *opt)
>  {
>       switch (ch) {
> @@ -444,6 +443,82 @@ static struct sd_option node_options[] = {
>       { 0, NULL, false, NULL },
>  };
>  
> +static int node_loglevel_set(int argc, char **argv)
> +{
> +     int ret = 0;
> +     char *loglevel_str = argv[optind];
> +
> +     ret = do_loglevel_set(&sd_nid, loglevel_str);
> +     switch (ret) {
> +     case EXIT_USAGE:
> +             sd_err("invalid loglevel: %s", loglevel_str);
> +             sd_err("available loglevels:");
> +             dump_loglevels(true);
> +
> +             ret = -1;
> +             break;
> +     case EXIT_FAILURE:
> +     case EXIT_SYSFAIL:
> +             sd_err("Failed to execute request");
> +             ret = -1;
> +             break;
> +     case EXIT_SUCCESS:
> +             /* do nothing */
> +             break;
> +     default:
> +             sd_err("unknown return code of do_loglevel_set(): %d", ret);
> +             ret = -1;
> +             break;
> +     }

I think set/get can share the same switch case handling.

Thanks
Yuan
-- 
sheepdog mailing list
sheepdog@lists.wpkg.org
http://lists.wpkg.org/mailman/listinfo/sheepdog

Reply via email to