Print this page
OS-1840 fmdump shall emit JSON
Reviewed by: Robert Mustacchi <rm@joyent.com>

Split Close
Expand all
Collapse all
          --- old/usr/src/cmd/fm/fmdump/common/fmdump.c
          +++ new/usr/src/cmd/fm/fmdump/common/fmdump.c
↓ open down ↓ 14 lines elided ↑ open up ↑
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  
  22   22  /*
  23   23   * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
  24   24   * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
       25 + * Copyright (c) 2013, Joyent, Inc. All rights reserved.
  25   26   */
  26   27  
  27   28  #include <alloca.h>
  28   29  #include <unistd.h>
  29   30  #include <limits.h>
  30   31  #include <strings.h>
  31   32  #include <stdlib.h>
  32   33  #include <stdarg.h>
  33   34  #include <stdio.h>
  34   35  #include <errno.h>
↓ open down ↓ 151 lines elided ↑ open up ↑
 186  187          "\t-i  display infolog content\n"
 187  188          "\t-I  display the high-value-infolog content\n"
 188  189          "\t-R  set root directory for pathname expansions\n    "
 189  190      "Command behaviour:\n"
 190  191          "\t-A  Aggregate specified [file]s or, if no [file], all known logs\n"
 191  192          "\t-f  follow growth of log file by waiting for additional data\n    "
 192  193      "Output options:\n"
 193  194          "\t-m  display human-readable messages (only for fault logs)\n"
 194  195          "\t-v  set verbose mode: display additional event detail\n"
 195  196          "\t-V  set very verbose mode: display complete event contents\n"
 196      -        "\t-p  Used with -V: apply some output prettification\n    "
      197 +        "\t-p  Used with -V: apply some output prettification\n"
      198 +        "\t-j  Used with -V: emit JSON-formatted output\n    "
 197  199      "Selection filters:\n"
 198  200          "\t-c  select events that match the specified class\n"
 199  201          "\t-t  select events that occurred after the specified time\n"
 200  202          "\t-T  select events that occurred before the specified time\n"
 201  203          "\t-u  select events that match the specified diagnosis uuid\n"
 202  204          "\t-n  select events containing named nvpair (with matching value)\n";
 203  205  /* END CSTYLED */
 204  206  
 205  207  static int
 206  208  usage(FILE *fp)
↓ open down ↓ 813 lines elided ↑ open up ↑
1020 1022          pipeline_process(pl, pl->pl_logpath, pl->pl_follow);
1021 1023          pipeline_done(pl);
1022 1024  
1023 1025          return (NULL);
1024 1026  }
1025 1027  
1026 1028  
1027 1029  static int
1028 1030  aggregate(char **ifiles, int n_ifiles, int opt_f,
1029 1031      fmd_log_filter_t *fv, uint_t fc,
1030      -    int opt_v, int opt_V, int opt_p)
     1032 +    int opt_v, int opt_V, int opt_p, int opt_j)
1031 1033  {
1032 1034          struct fmdump_pipeline *pipeline, *pl;
1033 1035          struct fmdump_srlzer srlzer;
1034 1036          uint32_t npipe;
1035 1037          int fmt;
1036 1038          int i;
1037 1039  
1038 1040          if (ifiles != NULL) {
1039 1041                  npipe = n_ifiles;
1040 1042                  pipeline = calloc(npipe, sizeof (struct fmdump_pipeline));
↓ open down ↓ 26 lines elided ↑ open up ↑
1067 1069                              g_root ? g_root : "", ltp->lt_logname);
1068 1070  
1069 1071                          pipeline[npipe].pl_rotated =
1070 1072                              get_rotated_logs(logpath);
1071 1073  
1072 1074                          pipeline[npipe++].pl_logpath = logpath;
1073 1075                  }
1074 1076          }
1075 1077  
1076 1078          if (opt_V)
1077      -                fmt = opt_p ? FMDUMP_PRETTY : FMDUMP_VERB2;
     1079 +                fmt = opt_p ? FMDUMP_PRETTY : opt_j ? FMDUMP_JSON :
     1080 +                    FMDUMP_VERB2;
1078 1081          else if (opt_v)
1079 1082                  fmt = FMDUMP_VERB1;
1080 1083          else
1081 1084                  fmt = FMDUMP_SHORT;
1082 1085  
1083 1086          bzero(&srlzer, sizeof (srlzer));
1084 1087          srlzer.ds_pipearr = pipeline;
1085 1088          srlzer.ds_pipecnt = npipe;
1086 1089          srlzer.ds_slot = calloc(npipe, sizeof (struct fmdump_srlzer_slot));
1087 1090          if (!srlzer.ds_slot)
↓ open down ↓ 57 lines elided ↑ open up ↑
1145 1148                  }
1146 1149          }
1147 1150  
1148 1151          free(ifiles);
1149 1152  }
1150 1153  
1151 1154  int
1152 1155  main(int argc, char *argv[])
1153 1156  {
1154 1157          int opt_a = 0, opt_e = 0, opt_f = 0, opt_H = 0, opt_m = 0, opt_p = 0;
1155      -        int opt_u = 0, opt_v = 0, opt_V = 0;
     1158 +        int opt_u = 0, opt_v = 0, opt_V = 0, opt_j = 0;
1156 1159          int opt_i = 0, opt_I = 0;
1157 1160          int opt_A = 0;
1158 1161          char **ifiles = NULL;
1159 1162          char *ifile = NULL;
1160 1163          int n_ifiles;
1161 1164          int ifileidx = 0;
1162 1165          int iflags = 0;
1163 1166  
1164 1167          fmdump_arg_t arg;
1165 1168          fmdump_lyr_t lyr;
↓ open down ↓ 14 lines elided ↑ open up ↑
1180 1183          struct loglink *rotated_logs = NULL, *llp;
1181 1184  
1182 1185          g_pname = argv[0];
1183 1186  
1184 1187          errfv = alloca(sizeof (fmd_log_filter_t) * argc);
1185 1188          fltfv = alloca(sizeof (fmd_log_filter_t) * argc);
1186 1189          allfv = alloca(sizeof (fmd_log_filter_t) * argc);
1187 1190  
1188 1191          while (optind < argc) {
1189 1192                  while ((c =
1190      -                    getopt(argc, argv, "Aac:efHiImn:O:pR:t:T:u:vV")) != EOF) {
     1193 +                    getopt(argc, argv, "Aac:efHiIjmn:O:pR:t:T:u:vV")) != EOF) {
1191 1194                          switch (c) {
1192 1195                          case 'A':
1193 1196                                  opt_A++;
1194 1197                                  break;
1195 1198                          case 'a':
1196 1199                                  opt_a++;
1197 1200                                  break;
1198 1201                          case 'c':
1199 1202                                  errfv[errfc].filt_func = fmd_log_filter_class;
1200 1203                                  errfv[errfc].filt_arg = optarg;
↓ open down ↓ 13 lines elided ↑ open up ↑
1214 1217                          case 'i':
1215 1218                                  if (opt_e || opt_I)
1216 1219                                          return (usage(stderr));
1217 1220                                  opt_i++;
1218 1221                                  break;
1219 1222                          case 'I':
1220 1223                                  if (opt_e || opt_i)
1221 1224                                          return (usage(stderr));
1222 1225                                  opt_I++;
1223 1226                                  break;
     1227 +                        case 'j':
     1228 +                                if (opt_p)
     1229 +                                        return (usage(stderr));
     1230 +                                opt_j++;
     1231 +                                break;
1224 1232                          case 'm':
1225 1233                                  opt_m++;
1226 1234                                  break;
1227 1235                          case 'O':
1228 1236                                  off = strtoull(optarg, NULL, 16);
1229 1237                                  iflags |= FMD_LOG_XITER_OFFS;
1230 1238                                  break;
1231 1239                          case 'p':
     1240 +                                if (opt_j)
     1241 +                                        return (usage(stderr));
1232 1242                                  opt_p++;
1233 1243                                  break;
1234 1244                          case 'R':
1235 1245                                  g_root = optarg;
1236 1246                                  break;
1237 1247                          case 't':
1238 1248                                  errfv[errfc].filt_func = fmd_log_filter_after;
1239 1249                                  errfv[errfc].filt_arg = gettimeopt(optarg);
1240 1250                                  allfv[allfc++] = errfv[errfc++];
1241 1251                                  break;
↓ open down ↓ 60 lines elided ↑ open up ↑
1302 1312                  int rc;
1303 1313  
1304 1314                  if (!opt_a) {
1305 1315                          fltfv[fltfc].filt_func = log_filter_silent;
1306 1316                          fltfv[fltfc].filt_arg = (void *)1;
1307 1317                          allfv[allfc++] = fltfv[fltfc++];
1308 1318                  }
1309 1319  
1310 1320                  rc = aggregate(ifiles, n_ifiles, opt_f,
1311 1321                      allfv, allfc,
1312      -                    opt_v, opt_V, opt_p);
     1322 +                    opt_v, opt_V, opt_p, opt_j);
1313 1323  
1314 1324                  cleanup(ifiles, n_ifiles);
1315 1325                  return (rc);
1316 1326          } else {
1317 1327                  if (ifiles == NULL) {
1318 1328                          if ((ifile = calloc(1, PATH_MAX)) == NULL)
1319 1329                                  fmdump_fatal("failed to allocate memory");
1320 1330                  } else {
1321 1331                          ifile = ifiles[0];
1322 1332                  }
↓ open down ↓ 70 lines elided ↑ open up ↑
1393 1403                  ops = &fmdump_err_ops;
1394 1404  
1395 1405          if (!opt_a && ops == &fmdump_flt_ops) {
1396 1406                  fltfv[fltfc].filt_func = log_filter_silent;
1397 1407                  fltfv[fltfc].filt_arg = NULL;
1398 1408                  allfv[allfc++] = fltfv[fltfc++];
1399 1409          }
1400 1410  
1401 1411          if (opt_V) {
1402 1412                  arg.da_fmt =
1403      -                    &ops->do_formats[opt_p ? FMDUMP_PRETTY : FMDUMP_VERB2];
     1413 +                    &ops->do_formats[opt_p ? FMDUMP_PRETTY :
     1414 +                    opt_j ? FMDUMP_JSON : FMDUMP_VERB2];
1404 1415                  iflags |= FMD_LOG_XITER_REFS;
1405 1416          } else if (opt_v) {
1406 1417                  arg.da_fmt = &ops->do_formats[FMDUMP_VERB1];
1407 1418          } else if (opt_m) {
1408 1419                  arg.da_fmt = &ops->do_formats[FMDUMP_MSG];
1409 1420          } else
1410 1421                  arg.da_fmt = &ops->do_formats[FMDUMP_SHORT];
1411 1422  
1412 1423          if (opt_m && arg.da_fmt->do_func == NULL) {
1413 1424                  fmdump_usage("-m mode is not supported for "
↓ open down ↓ 88 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX