blob: 169a823d990a1c773c2bc0891862437c7e96a1b3 [file] [log] [blame] [edit]
/*****************************************************************************\
* sreport.c - report generating tool for slurm accounting.
*****************************************************************************
* Copyright (C) 2008 Lawrence Livermore National Security.
* Copyright (C) 2002-2007 The Regents of the University of California.
* Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
* Written by Danny Auble <da@llnl.gov>
* CODE-OCEC-09-009. All rights reserved.
*
* This file is part of SLURM, a resource management program.
* For details, see <http://slurm.schedmd.com/>.
* Please also read the included file: DISCLAIMER.
*
* SLURM is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* In addition, as a special exception, the copyright holders give permission
* to link the code of portions of this program with the OpenSSL library under
* certain conditions as described in each individual source file, and
* distribute linked combinations including the two. You must obey the GNU
* General Public License in all respects for all of the code used other than
* OpenSSL. If you modify file(s) with this exception, you may extend this
* exception to your version of the file(s), but you are not obligated to do
* so. If you do not wish to do so, delete this exception statement from your
* version. If you delete this exception statement from all source files in
* the program, then also delete it here.
*
* SLURM is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along
* with SLURM; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
\*****************************************************************************/
#include "src/sreport/sreport.h"
#include "src/sreport/assoc_reports.h"
#include "src/sreport/cluster_reports.h"
#include "src/sreport/job_reports.h"
#include "src/sreport/resv_reports.h"
#include "src/sreport/user_reports.h"
#include "src/common/xsignal.h"
#include "src/common/proc_args.h"
#define OPT_LONG_HIDE 0x102
#define BUFFER_SIZE 4096
char *command_name;
int exit_code; /* sreport's exit code, =1 on any error at any time */
int exit_flag; /* program to terminate if =1 */
int input_words; /* number of words of input permitted */
int quiet_flag; /* quiet=1, verbose=-1, normal=0 */
int all_clusters_flag = 0;
slurmdb_report_time_format_t time_format = SLURMDB_REPORT_TIME_MINS;
char *time_format_string = "Minutes";
void *db_conn = NULL;
uint32_t my_uid = 0;
slurmdb_report_sort_t sort_flag = SLURMDB_REPORT_SORT_TIME;
static void _job_rep (int argc, char *argv[]);
static void _user_rep (int argc, char *argv[]);
static void _resv_rep (int argc, char *argv[]);
static void _cluster_rep (int argc, char *argv[]);
static void _assoc_rep (int argc, char *argv[]);
static int _get_command (int *argc, char *argv[]);
static void _print_version( void );
static int _process_command (int argc, char *argv[]);
static int _set_time_format(char *format);
static int _set_sort(char *format);
static void _usage ();
int
main (int argc, char *argv[])
{
int error_code = SLURM_SUCCESS, i, opt_char, input_field_count;
char **input_fields;
log_options_t opts = LOG_OPTS_STDERR_ONLY ;
char *temp = NULL;
int option_index;
static struct option long_options[] = {
{"all_clusters", 0, 0, 'a'},
{"help", 0, 0, 'h'},
{"immediate",0, 0, 'i'},
{"noheader", 0, 0, 'n'},
{"parsable", 0, 0, 'p'},
{"parsable2",0, 0, 'P'},
{"quiet", 0, 0, 'Q'},
{"sort", 0, 0, 's'},
{"usage", 0, 0, 'h'},
{"verbose", 0, 0, 'v'},
{"version", 0, 0, 'V'},
{NULL, 0, 0, 0}
};
command_name = argv[0];
exit_code = 0;
exit_flag = 0;
input_field_count = 0;
quiet_flag = 0;
slurm_conf_init(NULL);
log_init("sreport", opts, SYSLOG_FACILITY_DAEMON, NULL);
/* Check to see if we are running a supported accounting plugin */
temp = slurm_get_accounting_storage_type();
if (strcasecmp(temp, "accounting_storage/slurmdbd")
&& strcasecmp(temp, "accounting_storage/mysql")) {
fprintf (stderr, "You are not running a supported "
"accounting_storage plugin\n(%s).\n"
"Only 'accounting_storage/slurmdbd' "
"and 'accounting_storage/mysql' are supported.\n",
temp);
xfree(temp);
exit(1);
}
xfree(temp);
while((opt_char = getopt_long(argc, argv, "ahnpPQs:t:vV",
long_options, &option_index)) != -1) {
switch (opt_char) {
case (int)'?':
fprintf(stderr, "Try \"sreport --help\" "
"for more information\n");
exit(1);
break;
case (int)'h':
_usage ();
exit(exit_code);
break;
case (int)'a':
all_clusters_flag = 1;
break;
case (int)'n':
print_fields_have_header = 0;
break;
case (int)'p':
print_fields_parsable_print =
PRINT_FIELDS_PARSABLE_ENDING;
break;
case (int)'P':
print_fields_parsable_print =
PRINT_FIELDS_PARSABLE_NO_ENDING;
break;
case (int)'Q':
quiet_flag = 1;
break;
case (int)'s':
_set_sort(optarg);
break;
case (int)'t':
_set_time_format(optarg);
break;
case (int)'v':
quiet_flag = -1;
break;
case (int)'V':
_print_version();
exit(exit_code);
break;
default:
exit_code = 1;
fprintf(stderr, "getopt error, returned %c\n",
opt_char);
exit(exit_code);
}
}
if (argc > MAX_INPUT_FIELDS) /* bogus input, but continue anyway */
input_words = argc;
else
input_words = 128;
input_fields = (char **) xmalloc (sizeof (char *) * input_words);
if (optind < argc) {
for (i = optind; i < argc; i++) {
input_fields[input_field_count++] = argv[i];
}
}
db_conn = slurmdb_connection_get();
if (errno) {
error("Problem talking to the database: %m");
exit(1);
}
my_uid = getuid();
if (input_field_count)
exit_flag = 1;
else
error_code = _get_command (&input_field_count, input_fields);
while (error_code == SLURM_SUCCESS) {
error_code = _process_command (input_field_count,
input_fields);
if (error_code || exit_flag)
break;
error_code = _get_command (&input_field_count, input_fields);
}
if (exit_flag == 2)
putchar('\n');
slurmdb_connection_close(&db_conn);
slurm_acct_storage_fini();
exit(exit_code);
}
#if !HAVE_READLINE
/*
* Alternative to readline if readline is not available
*/
static char *_getline(const char *prompt)
{
char buf[4096];
char *line;
int len;
printf("%s", prompt);
/* Set "line" here to avoid a warning, discard later */
line = fgets(buf, 4096, stdin);
if (line == NULL)
return NULL;
len = strlen(buf);
if ((len == 0) || (len >= 4096))
return NULL;
if (buf[len-1] == '\n')
buf[len-1] = '\0';
else
len++;
line = malloc(len * sizeof(char));
if (!line)
return NULL;
return strncpy(line, buf, len);
}
#endif
/*
* _job_rep - Reports having to do with jobs
* IN argc - count of arguments
* IN argv - list of arguments
*/
static void _job_rep (int argc, char *argv[])
{
int error_code = SLURM_SUCCESS;
int command_len = strlen(argv[0]);
/* For backwards compatibility we just look at the 1st char
* by default since Sizes was the original name */
if (!strncasecmp (argv[0], "SizesByAccount", MAX(command_len, 1))) {
error_code = job_sizes_grouped_by_top_acct(
(argc - 1), &argv[1]);
} else if (!strncasecmp (argv[0],
"SizesByWcKey", MAX(command_len, 8))) {
error_code = job_sizes_grouped_by_wckey(
(argc - 1), &argv[1]);
} else if (!strncasecmp (argv[0],
"SizesByAccountAndWcKey",
MAX(command_len, 15))) {
error_code = job_sizes_grouped_by_top_acct_and_wckey(
(argc - 1), &argv[1]);
} else {
exit_code = 1;
fprintf(stderr, "Not valid report %s\n", argv[0]);
fprintf(stderr, "Valid job reports are, ");
fprintf(stderr, "\"SizesByAccount, SizesByAccountAndWcKey, ");
fprintf(stderr, "and SizesByWckey\"\n");
}
if (error_code) {
exit_code = 1;
}
}
/*
* _user_rep - Reports having to do with users
* IN argc - count of arguments
* IN argv - list of arguments
*/
static void _user_rep (int argc, char *argv[])
{
int error_code = SLURM_SUCCESS;
if (strncasecmp (argv[0], "Top", 1) == 0) {
error_code = user_top((argc - 1), &argv[1]);
} else {
exit_code = 1;
fprintf(stderr, "Not valid report %s\n", argv[0]);
fprintf(stderr, "Valid user reports are, ");
fprintf(stderr, "\"Top\"\n");
}
if (error_code) {
exit_code = 1;
}
}
/*
* _resv_rep - Reports having to do with reservations
* IN argc - count of arguments
* IN argv - list of arguments
*/
static void _resv_rep (int argc, char *argv[])
{
int error_code = SLURM_SUCCESS;
if (strncasecmp (argv[0], "Utilization", 1) == 0) {
error_code = resv_utilization((argc - 1), &argv[1]);
} else {
exit_code = 1;
fprintf(stderr, "Not valid report %s\n", argv[0]);
fprintf(stderr, "Valid reservation reports are, ");
fprintf(stderr, "\"Utilization\"\n");
}
if (error_code) {
exit_code = 1;
}
}
/*
* _cluster_rep - Reports having to do with clusters
* IN argc - count of arguments
* IN argv - list of arguments
*/
static void _cluster_rep (int argc, char *argv[])
{
int error_code = SLURM_SUCCESS;
if (strncasecmp (argv[0], "AccountUtilizationByUser", 1) == 0) {
error_code = cluster_account_by_user((argc - 1), &argv[1]);
} else if ((strncasecmp (argv[0], "UserUtilizationByAccount", 18) == 0)
|| (strncasecmp (argv[0], "UA", 2) == 0)) {
error_code = cluster_user_by_account((argc - 1), &argv[1]);
} else if ((strncasecmp (argv[0], "UserUtilizationByWckey", 18) == 0)
|| (strncasecmp (argv[0], "UW", 2) == 0)) {
error_code = cluster_user_by_wckey((argc - 1), &argv[1]);
} else if (strncasecmp (argv[0], "Utilization", 2) == 0) {
error_code = cluster_utilization((argc - 1), &argv[1]);
} else if (strncasecmp (argv[0], "WCKeyUtilizationByUser", 1) == 0) {
error_code = cluster_wckey_by_user((argc - 1), &argv[1]);
} else {
exit_code = 1;
fprintf(stderr, "Not valid report %s\n", argv[0]);
fprintf(stderr, "Valid cluster reports are, ");
fprintf(stderr, "\"AccountUtilizationByUser\", "
"\"UserUtilizationByAccount\", "
"\"UserUtilizationByWckey\", \"Utilization\", "
"and \"WCKeyUtilizationByUser\"\n");
}
if (error_code) {
exit_code = 1;
}
}
/*
* _assoc_rep - Reports having to do with jobs
* IN argc - count of arguments
* IN argv - list of arguments
*/
static void _assoc_rep (int argc, char *argv[])
{
int error_code = SLURM_SUCCESS;
if (error_code) {
exit_code = 1;
}
}
/*
* _get_command - get a command from the user
* OUT argc - location to store count of arguments
* OUT argv - location to store the argument list
*/
static int
_get_command (int *argc, char **argv)
{
char *in_line;
static char *last_in_line = NULL;
int i, in_line_size;
static int last_in_line_size = 0;
*argc = 0;
#if HAVE_READLINE
in_line = readline ("sreport: ");
#else
in_line = _getline("sreport: ");
#endif
if (in_line == NULL) {
exit_flag = 2;
return 0;
}
else if (strncmp (in_line, "#", 1) == 0) {
free (in_line);
return 0;
} else if (strcmp (in_line, "!!") == 0) {
free (in_line);
in_line = last_in_line;
in_line_size = last_in_line_size;
} else {
if (last_in_line)
free (last_in_line);
last_in_line = in_line;
last_in_line_size = in_line_size = strlen (in_line);
}
#if HAVE_READLINE
add_history(in_line);
#endif
/* break in_line into tokens */
for (i = 0; i < in_line_size; i++) {
bool double_quote = false, single_quote = false;
if (in_line[i] == '\0')
break;
if (isspace ((int) in_line[i]))
continue;
if (((*argc) + 1) > MAX_INPUT_FIELDS) { /* bogus input line */
exit_code = 1;
fprintf (stderr,
"%s: can not process over %d words\n",
command_name, input_words);
return E2BIG;
}
argv[(*argc)++] = &in_line[i];
for (i++; i < in_line_size; i++) {
if (in_line[i] == '\042') {
double_quote = !double_quote;
continue;
}
if (in_line[i] == '\047') {
single_quote = !single_quote;
continue;
}
if (in_line[i] == '\0')
break;
if (double_quote || single_quote)
continue;
if (isspace ((int) in_line[i])) {
in_line[i] = '\0';
break;
}
}
}
return 0;
}
static void _print_version(void)
{
print_slurm_version ();
if (quiet_flag == -1) {
long version = slurm_api_version();
printf("slurm_api_version: %ld, %ld.%ld.%ld\n", version,
SLURM_VERSION_MAJOR(version),
SLURM_VERSION_MINOR(version),
SLURM_VERSION_MICRO(version));
}
}
/*
* _process_command - process the user's command
* IN argc - count of arguments
* IN argv - the arguments
* RET 0 or errno (only for errors fatal to sreport)
*/
static int
_process_command (int argc, char *argv[])
{
int command_len = 0;
if (argc < 1) {
exit_code = 1;
if (quiet_flag == -1)
fprintf(stderr, "no input");
return 0;
}
command_len = strlen(argv[0]);
if ((strncasecmp (argv[0], "association", MAX(command_len, 1)) == 0)) {
if (argc < 2) {
exit_code = 1;
if (quiet_flag != 1)
fprintf(stderr,
"too few arguments for keyword:%s\n",
argv[0]);
} else
_assoc_rep((argc - 1), &argv[1]);
} else if ((strncasecmp (argv[0], "cluster",
MAX(command_len, 2)) == 0)) {
if (argc < 2) {
exit_code = 1;
if (quiet_flag != 1)
fprintf(stderr,
"too few arguments for keyword:%s\n",
argv[0]);
} else
_cluster_rep((argc - 1), &argv[1]);
} else if (strncasecmp (argv[0], "help", MAX(command_len, 2)) == 0) {
if (argc > 1) {
exit_code = 1;
fprintf (stderr,
"too many arguments for keyword:%s\n",
argv[0]);
}
_usage ();
} else if ((strncasecmp (argv[0], "job", MAX(command_len, 1)) == 0)) {
if (argc < 2) {
exit_code = 1;
if (quiet_flag != 1)
fprintf(stderr,
"too few arguments for keyword:%s\n",
argv[0]);
} else
_job_rep((argc - 1), &argv[1]);
} else if (strncasecmp (argv[0], "quiet", MAX(command_len, 4)) == 0) {
if (argc > 1) {
exit_code = 1;
fprintf (stderr, "too many arguments for keyword:%s\n",
argv[0]);
}
quiet_flag = 1;
} else if ((strncasecmp (argv[0], "exit", MAX(command_len, 1)) == 0) ||
(strncasecmp (argv[0], "\\q", MAX(command_len, 2)) == 0) ||
(strncasecmp (argv[0], "quit", MAX(command_len, 4)) == 0)) {
if (argc > 1) {
exit_code = 1;
fprintf (stderr,
"too many arguments for keyword:%s\n",
argv[0]);
}
exit_flag = 1;
} else if (strncasecmp (argv[0], "nonparsable",
MAX(command_len, 4)) == 0) {
if (argc > 1) {
exit_code = 1;
fprintf (stderr, "too many arguments for keyword:%s\n",
argv[0]);
}
print_fields_parsable_print = 0;
} else if (strncasecmp (argv[0], "parsable",
MAX(command_len, 8)) == 0) {
if (argc > 1) {
exit_code = 1;
fprintf (stderr, "too many arguments for keyword:%s\n",
argv[0]);
}
print_fields_parsable_print = PRINT_FIELDS_PARSABLE_ENDING;
} else if (strncasecmp (argv[0], "parsable2",
MAX(command_len, 9)) == 0) {
if (argc > 1) {
exit_code = 1;
fprintf (stderr, "too many arguments for keyword:%s\n",
argv[0]);
}
print_fields_parsable_print = PRINT_FIELDS_PARSABLE_NO_ENDING;
} else if ((strncasecmp (argv[0], "reservation",
MAX(command_len, 2)) == 0)
|| (strncasecmp (argv[0], "resv",
MAX(command_len, 2)) == 0)) {
if (argc < 2) {
exit_code = 1;
if (quiet_flag != 1)
fprintf(stderr,
"too few arguments for keyword:%s\n",
argv[0]);
} else
_resv_rep((argc - 1), &argv[1]);
} else if (strncasecmp (argv[0], "sort", MAX(command_len, 1)) == 0) {
if (argc < 2) {
exit_code = 1;
fprintf (stderr,
"too few arguments for keyword:%s\n",
argv[0]);
} else
_set_sort(argv[1]);
} else if (strncasecmp (argv[0], "time", MAX(command_len, 1)) == 0) {
if (argc < 2) {
exit_code = 1;
fprintf (stderr,
"too few arguments for keyword:%s\n",
argv[0]);
} else
_set_time_format(argv[1]);
} else if (strncasecmp (argv[0], "verbose", MAX(command_len, 4)) == 0) {
if (argc > 1) {
exit_code = 1;
fprintf (stderr,
"too many arguments for %s keyword\n",
argv[0]);
}
quiet_flag = -1;
} else if (strncasecmp (argv[0], "version", MAX(command_len, 4)) == 0) {
if (argc > 1) {
exit_code = 1;
fprintf (stderr,
"too many arguments for %s keyword\n",
argv[0]);
}
_print_version();
} else if ((strncasecmp (argv[0], "user", MAX(command_len, 1)) == 0)) {
if (argc < 2) {
exit_code = 1;
if (quiet_flag != 1)
fprintf(stderr,
"too few arguments for keyword:%s\n",
argv[0]);
} else
_user_rep((argc - 1), &argv[1]);
} else {
exit_code = 1;
fprintf (stderr, "invalid keyword: %s\n", argv[0]);
}
return 0;
}
static int _set_time_format(char *format)
{
int command_len = strlen(format);
if (strncasecmp (format, "SecPer", MAX(command_len, 6)) == 0) {
time_format = SLURMDB_REPORT_TIME_SECS_PER;
time_format_string = "Seconds/Percentage of Total";
} else if (strncasecmp (format, "MinPer", MAX(command_len, 6)) == 0) {
time_format = SLURMDB_REPORT_TIME_MINS_PER;
time_format_string = "Minutes/Percentage of Total";
} else if (strncasecmp (format, "HourPer", MAX(command_len, 6)) == 0) {
time_format = SLURMDB_REPORT_TIME_HOURS_PER;
time_format_string = "Hours/Percentage of Total";
} else if (strncasecmp (format, "Seconds", MAX(command_len, 1)) == 0) {
time_format = SLURMDB_REPORT_TIME_SECS;
time_format_string = "Seconds";
} else if (strncasecmp (format, "Minutes", MAX(command_len, 1)) == 0) {
time_format = SLURMDB_REPORT_TIME_MINS;
time_format_string = "Minutes";
} else if (strncasecmp (format, "Hours", MAX(command_len, 1)) == 0) {
time_format = SLURMDB_REPORT_TIME_HOURS;
time_format_string = "Hours";
} else if (strncasecmp (format, "Percent", MAX(command_len, 1)) == 0) {
time_format = SLURMDB_REPORT_TIME_PERCENT;
time_format_string = "Percentage of Total";
} else {
fprintf (stderr, "unknown time format %s", format);
return SLURM_ERROR;
}
return SLURM_SUCCESS;
}
static int _set_sort(char *format)
{
int command_len = strlen(format);
if (strncasecmp (format, "Name", MAX(command_len, 1)) == 0) {
sort_flag = SLURMDB_REPORT_SORT_NAME;
} else if (strncasecmp (format, "Time", MAX(command_len, 6)) == 0) {
sort_flag = SLURMDB_REPORT_SORT_TIME;
} else {
fprintf (stderr, "unknown timesort format %s", format);
return SLURM_ERROR;
}
return SLURM_SUCCESS;
}
/* _usage - show the valid sreport commands */
void _usage () {
printf ("\
sreport [<OPTION>] [<COMMAND>] \n\
Valid <OPTION> values are: \n\
-a or --all_clusters: Use all clusters instead of current \n\
-h or --help: equivalent to \"help\" command \n\
-n or --noheader: equivalent to \"noheader\" command \n\
-p or --parsable: output will be '|' delimited with a '|' at the end \n\
-P or --parsable2: output will be '|' delimited without a '|' at the end\n\
-Q or --quiet: equivalent to \"quiet\" command \n\
-t <time_format>: Second, Minute, Hour, Percent, SecPer, MinPer, HourPer\n\
-v or --verbose: equivalent to \"verbose\" command \n\
-V or --version: equivalent to \"version\" command \n\
\n\
<keyword> may be omitted from the execute line and sreport will execute \n\
in interactive mode. It will process commands as entered until explicitly\n\
terminated. \n\
\n\
Valid <COMMAND> values are: \n\
exit Terminate sreport \n\
help Print this description of use. \n\
nonparsable Return output to normal \n\
parsable Output will be | delimited with an ending '|' \n\
parsable2 Output will be | delimited without an ending '|' \n\
quiet Print no messages other than error messages. \n\
quit Terminate this command. \n\
time <time_format> Second, Minute, Hour, Percent, SecPer, MinPer, HourPer\n\
verbose Enable detailed logging. \n\
version Display tool version number. \n\
!! Repeat the last command entered. \n\
\n\
Valid report types are: \n\
cluster <REPORT> <OPTIONS> \n\
job <REPORT> <OPTIONS> \n\
user <REPORT> <OPTIONS> \n\
\n\
<REPORT> is different for each report type. \n\
cluster - AccountUtilizationByUser, UserUtilizationByAccount, \n\
UserUtilizationByWckey, Utilization, WCKeyUtilizationByUser \n\
job - SizesByAccount, SizesByAccountAndWckey, SizesByWckey \n\
reservation \n\
- Utilization \n\
user - TopUsage \n\
\n\
<OPTIONS> are different for each report type. \n\
\n\
COMMON FOR ALL TYPES \n\
- All_Clusters - Use all monitored clusters default is \n\
local cluster. \n\
- Clusters=<OPT> - List of clusters to include in report \n\
Default is local cluster. \n\
- End=<OPT> - Period ending for report. \n\
Default is 23:59:59 of previous day. \n\
- Format=<OPT> - Comma separated list of fields to display\n\
in report. \n\
- Start=<OPT> - Period start for report. \n\
Default is 00:00:00 of previous day. \n\
\n\
cluster - Accounts=<OPT> - When used with the UserUtilizationByAccount,\n\
or AccountUtilizationByUser, List of accounts\n\
to include in report. Default is all. \n\
- Tree - When used with the AccountUtilizationByUser\n\
report will span the accounts as they \n\
in the hierarchy. \n\
- Users=<OPT> - When used with any report other than \n\
Utilization, List of users to include in \n\
report. Default is all. \n\
- Wckeys=<OPT> - When used with the UserUtilizationByWckey\n\
or WCKeyUtilizationByUser, List of wckeys\n\
to include in report. Default is all. \n\
\n\
job - Accounts=<OPT> - List of accounts to use for the report \n\
Default is all. The SizesbyAccount(*) \n\
report only displays 1 hierarchical level.\n\
If accounts are specified the next layer \n\
of accounts under those specified will be\n\
displayed, not the accounts specified. \n\
In the SizesByAccount(*) reports the \n\
default for accounts is root. This \n\
explanation does not apply when ran with \n\
the FlatView option. \n\
- FlatView - When used with the SizesbyAccount(*) \n\
will not group accounts in a \n\
hierarchical level, but print each \n\
account where jobs ran on a separate \n\
line without any hierarchy. \n\
- GID=<OPT> - List of group ids to include in report. \n\
Default is all. \n\
- Grouping=<OPT> - Comma separated list of size groupings. \n\
(i.e. 50,100,150 would group job cpu count\n\
1-49, 50-99, 100-149, > 150). \n\
grouping=individual will result in a \n\
single column for each job size found. \n\
- Jobs=<OPT> - List of jobs/steps to include in report. \n\
Default is all. \n\
- Nodes=<OPT> - Only show jobs that ran on these nodes. \n\
Default is all. \n\
- Partitions=<OPT> - List of partitions jobs ran on to include\n\
in report. Default is all. \n\
- PrintJobCount - When used with the any Sizes report \n\
will print number of jobs ran instead of \n\
time used. \n\
- Users=<OPT> - List of users jobs to include in report. \n\
Default is all. \n\
- Wckeys=<OPT> - List of wckeys to use for the report. \n\
Default is all. The SizesbyWckey \n\
report all users summed together. If \n\
you want only certain users specify them \n\
them with the Users= option. \n\
\n\
reservation \n\
- Names=<OPT> - List of reservations to use for the report\n\
Default is all. \n\
- Nodes=<OPT> - Only show reservations that used these \n\
nodes. Default is all. \n\
\n\
user - Accounts=<OPT> - List of accounts to use for the report \n\
Default is all. \n\
- Group - Group all accounts together for each user.\n\
Default is a separate entry for each user\n\
and account reference. \n\
- TopCount=<OPT> - Used in the TopUsage report. Change the \n\
number of users displayed. Default is 10.\n\
- Users=<OPT> - List of users jobs to include in report. \n\
Default is all. \n\
\n\
Below are the format options for each report. \n\
\n\
One can get an number of characters by following the field option with \n\
a %%NUMBER option. i.e. format=name%%30 will print 30 chars of field name.\n\
\n\
Cluster \n\
- AccountUtilizationByUser \n\
- UserUtilizationByAccount \n\
- Accounts, Cluster, CPUCount, Login, Proper, Used \n\
- UserUtilizationByWckey \n\
- WCKeyUtilizationByUser \n\
- Cluster, CPUCount, Login, Proper, Used, Wckey \n\
- Utilization \n\
- Allocated, Cluster, CPUCount, Down, Idle, Overcommited, \n\
PlannedDown, Reported, Reserved \n\
\n\
Job \n\
- Sizes \n\
- Account, Cluster \n\
\n\
Reservation \n\
- Utilization \n\
- Allocated, Associations, Cluster, CPUCount, CPUTime, \n\
End, Idle, Name, Nodes, Start, TotalTime \n\
\n\
User \n\
- TopUsage \n\
- Account, Cluster, Login, Proper, Used \n\
\n\
\n\
Note, valid start/end time formats are... \n\
HH:MM[:SS] [AM|PM] \n\
MMDD[YY] or MM/DD[/YY] or MM.DD[.YY] \n\
MM/DD[/YY]-HH:MM[:SS] \n\
YYYY-MM-DD[THH:MM[:SS]] \n\
\n\
\n\
All commands and options are case-insensitive. \n\n");
}