Previous: , Up: I/O statements   [Contents][Index]

4.5.3 Writing to a log file

After performing a network correctness or performance test it is almost always desirable to store the results in a file. coNCePTuaL has language support for writing tabular data to a log file. The <log_stmt> command does the bulk of the work:

<log_stmt> ::= <source_task>
<aggr_expr> AS <string_or_log_comment>
[ AND <aggr_expr> AS <string_or_log_comment>]*

The idea behind a <log_stmt> is that a set of source tasks (see Source tasks) log an aggregate expression (see Aggregate expressions) to a log file under the column heading <string_or_log_comment>. Each task individually maintains a separately named log file so there is no ambiguity over which task wrote which entries.

Each (static) LOGS statement in a coNCePTuaL program specifies one or more columns of the log file. Every dynamic execution of a LOGS statement writes a single row to the log file. A single LOGS statement should suffice for most coNCePTuaL programs.

The following are some examples of <log_stmt>s:

ALL TASKS LOG bit_errors AS "Bit errors"

TASK 0 LOGS THE msgsize AS "Bytes" AND
            THE MEDIAN OF (1E6*bytes_sent)/(1M*elapsed_usecs) AS "MB/s"

The first example produces a log file like the following:

"Bit errors"
"(all data)"

The second example produces a log file like this:

"(only value)","(median)"

Note that in each log file, the coNCePTuaL run-time system writes two rows of column headers for each column. The first row contains <string_or_log_comment> as is. The second row describes the <aggr_func> (see Aggregate functions) used to aggregate the data. One or more rows of data follow.

Assume that the second <log_stmt> presented above appears within a loop (see Iterating). It is therefore important to include the THE keyword before ‘msgsize’ to assert that the expression ‘msgsize’ is constant across invocations of the <log_stmt> and that, consequently, only a single row of data should be written to the log file. Using ‘msgsize’ without the THE would produce a column of data with one row per <log_stmt> invocation:

"(all data)","(median)"

The rules that determine how LOGS statements produce rows and columns of a log file are presented below:

  1. Each static LOGS statement (and AND clause within a LOGS statement) in a program produces a unique column.
  2. Each dynamic execution of a LOGS statement appends a row to the column(s) it describes.
  3. Each top-level complex statement (see Complete programs) produces a new table in the log file.

Note that the choice of column name is inconsequential for determining what columns are written to the log file:

TASK 0 LOGS 314/100 AS "Pi" AND 22/7 AS "Pi"
"(all data)","(all data)"

As mentioned in Aggregate expressions, multiple <aggr_func> values can be specified per <aggr_expr>. This is a convenient feature when a coNCePTuaL program needs to compute multiple statistics over the same values while reusing the same description. For example,

ALL TASKS LOG THE MINIMUM OF bytes_received/elapsed_usecs AS
"Bandwidth (B/us)" AND THE MAXIMUM OF bytes_received/elapsed_usecs AS
"Bandwidth (B/us)" AND THE MEAN OF bytes_received/elapsed_usecs AS
"Bandwidth (B/us)" AND THE MEDIAN OF bytes_received/elapsed_usecs AS
"Bandwidth (B/us)"

can be shortened to

OF bytes_received/elapsed_usecs AS "Bandwidth (B/us)"

Previous: , Up: I/O statements   [Contents][Index]

Scott Pakin,