Experimental Custom Print Formats

condor_status, condor_q and condor_history each take the argument -pr[intf-format] <file> where <file> contains a print formatting description which has the following syntax:

SELECT [FROM AUTOCLUSTER | UNIQUE] [BARE | NOTITLE | NOHEADER | NOSUMMARY] [LABEL [SEPARATOR <string>]] [<record-sep>]
    <expr> [AS <label>] [PRINTF <format-string> | PRINTAS <function-name> | WIDTH [AUTO | [-]<INT>] ] [TRUNCATE] [LEFT | RIGHT] [NOPREFIX] [NOSUFFIX]
    ... repeat the above line as needed...
[WHERE <constraint-expr>]
[GROUP BY <sort-expr> [ASCENDING | DECENDING] ]
[SUMMARY [STANDARD | NONE]]
where
  • <string> is a string, delimited by either space, ' or "
  • <record-sep> is one or more of RECORDPREFIX <string>, RECORDSUFFIX <string>, FIELDPREFIX <string>, or FIELDSUFFIX <string>
  • FROM AUTOCLUSTER can be used with condor_q to query the schedd's default autocluster set. (requires version 8.3.6 or later)
  • UNIQUE can be used with condor_q to ask the schedd to count unique values. this is like building a FROM AUTOCLUSTER set on the fly. (requires version 8.5.1 or later)
  • <expr> is a Classad expression that extends from the start of the line until the first keyword (usually AS ).
  • <label> is a <string> used as a column heading, or as an item label when the LABEL keyword is used on the SELECT line.
  • <format-string> is a printf format specifier
  • <function-name> is the name of a formatting function
  • <constraint-expr> is a Classad expression that extends to the end of the line.
  • <sort-expr> is a Classad expression that extends to the next keyword.
  • Lines beginning with # are comments
  • Keywords are case sensitive, all uppercase and require whitespace on either side.
  • Escapes such as \n and \t are translated for most <string> arguments.
  • <string> may be wrapped in " or ', but can't contain imbedded quotes of the same type as the outer quote, because the parser currently doesn't support escaping of quotes.
  • If a <string> does not start with a single or double quote, then it is whitespace delimited.
  • Statements end at a newline, there is no line-continuation character.
  • GROUP BY currently only controls sorting, the code does not yet do any kind of aggregating.
  • PRINTAS , PRINTF & WIDTH are not entirely mutually exclusive, but more than one will play strangely together, there's actually a bunch of "intelligence" in the pretty printer code regarding the correct way to format strings vs numbers that's not desirable here but can't be disabled, you may need to play with combinations of formatting options to get things to line up perfectly. for instance negative WIDTH statements and the LEFT keyword should be interchangeable, but they aren't at present.
  • Available keywords for PRINTAS can be found only in the code. search for CustomFormatFnTable , you should find one table in queue.cpp and one in prettyPrint.cpp (for condor_status). Many PRINTAS functions are very specialized and pay little or no attention to the attribute that they are told to print. DATE , TIME , and QDATE are well behaved, but most of the others aren't.

You can set the default output of condor_status and/or condor_q to use one of these files by setting config parameters:

for condor_status

    STATUS_DEFAULT_<adtype>_PRINT_FORMAT_FILE=<file>
  • <adtype> can be one of the following ad type(s)
    DEFRAG, STARTD, SCHEDD, SUBMITTOR, MASTER, CKPT_SRVR, GATEWAYS, COLLECTOR, NEGOTIATOR, GRID, LICENSE, STORAGE, ANY, GENERIC

for condor_q

    Q_DEFAULT_PRINT_FORMAT_FILE=<file>
    Q_DEFAULT_<arg>_PRINT_FORMAT_FILE=<file>
  • <arg> can be RUN, HOLD, GOODPUT, GLOBUS, GRID corresponding to the -run, -hold, etc arguments to condor_q

Here are some sample print-format files

# queue.cpf
# produce the standard output of condor_q
SELECT
   ClusterId     AS " ID"  NOSUFFIX WIDTH 4
   ProcId        AS " "    NOPREFIX             PRINTF ".%-3d"
   Owner         AS "OWNER"         WIDTH -14   PRINTAS OWNER
   QDate         AS "  SUBMITTED"   WIDTH 11    PRINTAS QDATE
   {RemoteUserCpu,RemoteWallClockTime,ShadowBday,ServerTime}[0] AS "    RUN_TIME"  WIDTH 12    PRINTAS CPU_TIME
   JobStatus     AS ST                          PRINTAS JOB_STATUS
   JobPrio       AS PRI
   ImageSize     AS SIZE            WIDTH 4     PRINTAS MEMORY_USAGE
   Cmd           AS CMD             WIDTH -18   PRINTAS JOB_DESCRIPTION
SUMMARY STANDARD

# dagrun.cpf
# show hosts for f
SELECT
   ClusterId     AS " ID"  NOSUFFIX WIDTH 6
   ProcId        AS " "    NOPREFIX             PRINTF ".%-3d"
   Owner         AS "OWNER/NODENAME" WIDTH -17   PRINTAS DAG_OWNER
   QDate         AS "  SUBMITTED"   WIDTH 11    PRINTAS QDATE
   {RemoteUserCpu,RemoteWallClockTime,ShadowBday,ServerTime}[0] AS "    RUN_TIME"  WIDTH 12    PRINTAS CPU_TIME
   RemoteUserCpu AS "    RUN_TIME" WIDTH 12 PRINTAS CPU_TIME OR ??
   RemoteHost    AS "HOST(S)" PRINTAS REMOTE_HOST OR ??
WHERE JobStatus == 2
SUMMARY STANDARD

# q_totals.cpf
# show only totals with condor_q
SELECT NOHEADER NOTITLE
SUMMARY STANDARD

# status.cpf
# produce the standard output of condor_status
SELECT
   Name       AS Name     WIDTH -18 TRUNCATE
   OpSys      AS OpSys    WIDTH -10
   Arch       AS Arch     WIDTH -6
   State      AS State    WIDTH -9
   Activity   AS Activity WIDTH -8  TRUNCATE
   LoadAvg    AS LoadAv             PRINTAS LOAD_AVG
   Memory     AS Mem                PRINTF "%4d"
   EnteredCurrentActivity AS "  ActvtyTime\n" NOPREFIX PRINTAS ACTIVITY_TIME
SUMMARY STANDARD

# blackhole.cpf
# show static slots with high job churn
SELECT
   Machine WIDTH -24
   splitslotname(Name)[0] AS Slot WIDTH -8
   Strcat(Arch,"_",IfThenElse(OpSys=="WINDOWS",OpSysShortName,OpSysName)) AS Platform
   Cpus AS CPU
   Memory     PRINTF "%6d"     AS Mem
   Strcat(State,"/",Activity) AS Status WIDTH -14 TRUNCATE
   EnteredCurrentActivity AS "  StatusTime"  PRINTAS ACTIVITY_TIME NOPREFIX
   IfThenElse(JobId isnt undefined, JobId, "no") AS JobId WIDTH -11
   RecentJobStarts/20.0 AS J/Min PRINTF "%.2f"
WHERE RecentJobStarts >= 1 && PartitionableSlot =!= true && DynamicSlot =!= true
SUMMARY

# pairs.cpf
# condor_status query for slot pairs, use with condor_status -direct to see hidden pairs.
SELECT
   Machine WIDTH AUTO
   splitslotname(Name)[0] AS SlotName WIDTH -8
   IfThenElse(SlotPairName isnt undefined,splitslotname(SlotPairName)[0],"-") AS Paired
   Strcat(Arch,"_",IfThenElse(OpSys=="WINDOWS",OpSysShortName,OpSysAndVer)) AS Platform
   Cpus AS Cpus PRINTF "%.3f"
   # IfThenElse(GPUs isnt undefined,GPUs,0) AS GPUs PRINTF "%4d"
   Memory WIDTH 6
   Disk       WIDTH 8
   EnteredCurrentActivity AS "  StatusTime"  PRINTAS ACTIVITY_TIME NOPREFIX
   Strcat(State,"/",Activity) AS Status WIDTH -14 TRUNCATE
   ifthenelse(JobId isnt undefined, JobId, "") AS JobID
#   unparse(IsOwner) AS ISOWNER
   unparse(start) AS START
#   unparse(requirements) AS Requirements

# status_wide.cpf
# a wider version of standard condor_status output
SELECT
   Name       AS Name     WIDTH -34 TRUNCATE
   OpSys      AS OpSys    WIDTH -10
   Arch       AS Arch     WIDTH -6
   State      AS State    WIDTH -9
   Activity   AS Activity WIDTH -8
   LoadAvg    AS LoadAv             PRINTAS LOAD_AVG
   Memory     AS Memory             PRINTF "%6d"
   EnteredCurrentActivity AS "ActivityTime" PRINTAS ACTIVITY_TIME
SUMMARY STANDARD

# testy.cpf
# Improved condor_status output showing Gpus, compact platform & churn.
SELECT
   Machine WIDTH AUTO
   splitslotname(Name)[0] AS Slot WIDTH -8
   Strcat(Arch,"_",IfThenElse(OpSys=="WINDOWS",OpSysShortName,OpSysAndVer)) AS Platform
   Cpus AS CPU PRINTF "%3d"
   IfThenElse(GPUs isnt undefined,GPUs,0) AS GPUs PRINTF "%4d"
   Memory     PRINTF "%4d"     AS Mem
   Strcat(State,"/",Activity) AS Status WIDTH -14 TRUNCATE
   EnteredCurrentActivity AS "  StatusTime"  PRINTAS ACTIVITY_TIME NOPREFIX
   IfThenElse(JobId isnt undefined, JobId, "no") AS JobId WIDTH -6
   RecentJobStarts/20.0 AS J/Min PRINTF "%.2f"
GROUP BY Machine
SUMMARY

# status_long.cpf
# STARTD output in compact long format
SELECT RECORDPREFIX "\t***\n" RECORDSUFFIX "\n\n" FIELDPREFIX "\n" NOHEADER LABEL SEPARATOR "\t: "
    Machine AS "Machine\t"
    splitslotname(Name)[0] AS "Slot\t"
    strcat(Arch,"_",IfThenElse(OpSys=="WINDOWS",OpSysName,OpSysAndVer)) AS Platform
    strcat(State,"/",Activity) AS "State\t"
    EnteredCurrentActivity AS StateTime PRINTAS ACTIVITY_TIME PRINTF "%s"
    Cpus AS "Cpus\t"
    Memory AS "Memory\t"
    Disk   AS "Disk\t"

# status summary output for partitionable slots (8.1.6 or later for some fields)
SELECT
   Machine              AS Machine   WIDTH -32 TRUNCATE
   strcat(OpSysAndVer,"_x",substr(Arch,-2))  AS Platform WIDTH -8
   split(condorversion)[1] AS Condor
   TotalCpus            AS Cpus      PRINTF %4d
   Cpus                 AS Free      PRINTF %4d
   TotalMemory/1024.0   AS " Mem(Gb)" PRINTF %8.2f
   max(childmemory)     AS MaxMem   WIDTH 6 TRUNCATE
   Memory*100.0/TotalMemory AS FreeMem%  PRINTF %8.1f
   NumDynamicSlots      AS Slots    WIDTH 5 TRUNCATE
   TotalLoadAvg*1.0/TotalCpus  AS CpuUtil   PRINTF %7.2f
   RecentJobStarts/20.0  AS Jobs/Min PRINTF %8.2f
WHERE PartitionableSlot
SUMMARY NONE

# negotiator_autocluster.cpf
SELECT FROM AUTOCLUSTER
   Owner         AS OWNER         WIDTH -14   PRINTAS OWNER
   JobCount      AS COUNT                     PRINTF %5d
   AutoClusterId AS " ID"         WIDTH 3
   JobUniverse   AS UNI                       PRINTF %3d
   RequestMemory AS REQ_MEMORY    WIDTH 10    PRINTAS READABLE_MB
   RequestDisk   AS REQUEST_DISK  WIDTH 12    PRINTAS READABLE_KB
   JobIDs        AS JOBIDS
GROUP BY Owner

# count_jobs_by_owner.cpf
# aggregate by the given attributes, return unique values plus count and jobids.
# This query builds an autocluster set in the schedd on the fly using all of the displayed attributes
# And all of the GROUP BY attributes (except JobCount and JobIds)
SELECT UNIQUE NOSUMMARY
   Owner         AS OWNER      WIDTH -20
   JobUniverse   AS "UNIVERSE "   PRINTAS JOB_UNIVERSE
   JobStatus     AS STATUS     PRINTAS JOB_STATUS_RAW
   RequestCpus   AS CPUS
   RequestMemory AS MEMORY
   JobCount      AS COUNT      PRINTF  %5d
   JobIDs
GROUP BY
   Owner

# myqueue.cpf
# produce the standard output of condor_q + the custom attribute "Progress", showing only jobs for adam
SELECT
   ClusterId     AS " ID"  NOSUFFIX WIDTH 6
   ProcId        AS " "    NOPREFIX             PRINTF ".%-3d"
   Owner         AS "OWNER"         WIDTH -10   PRINTAS OWNER
   QDate         AS "  SUBMITTED"   WIDTH 11    PRINTAS QDATE
   {RemoteUserCpu,RemoteWallClockTime,ShadowBday,ServerTime}[0] AS "    RUN_TIME"  WIDTH 12    PRINTAS CPU_TIME
   JobStatus     AS ST                          PRINTAS JOB_STATUS
   NumJobStarts  AS RUNS
   ImageSize     AS SIZE            WIDTH 6     PRINTAS MEMORY_USAGE
   IfThenElse(Progress=!=undefined,Progress,0.0)  AS "DONE%" PRINTF "%5.1f"
   #Cmd           AS CMD             WIDTH -18   PRINTAS JOB_DESCRIPTION
   SubmitEventNotes AS NOTES        WIDTH -18
WHERE Owner=="adam"
SUMMARY STANDARD