MAINFRAME > Tips & Techniques > Application Development

REXX Offers Tools for Automated Processing of SMF Data

Editor’s note: This article is the second in a series exploring how to process Systems Management Facilities (SMF) data using the REXX programming language.

The first part of this series, “Leveraging SMF Data With (or Without) REXX,” outlined a basic understanding of the SMF record header and the various methods to view individual SMF records. Part one examined the IBM ERBSCAN and IDCAMS utilities and introduced a few manual techniques for translating the header fields into a more human-understandable format.

However, manual approaches can be tedious and error-prone, and this second part of the series introduces a few REXX building blocks to begin automating the analyses of SMF records.

Why Use REXX?

IBM provides macros that define the format of various SMF records in SYS1.MACLIB. The IBM-supplied IFASMFR macro is used as an interface to map all of the SMF records, a few directly and others by calling additional macros. However, only Assembler and PL/S definitions are provided. What if one doesn’t possess strong Assembler or PL/S coding skills? In this series, REXX was chosen to demonstrate the concepts and techniques discussed given its relative universality, and because it’s relatively easy to understand. It runs on every platform, including handheld devices, laptops, PCs, and servers all the way up to the largest mainframes.

It provides a set of built-in conversion functions that allow you to convert data between different formats, such as character, decimal, hexadecimal and binary strings. To convert the IDCAMS formatted dump output to a more user-friendly form, we'll need to use a few of these built-in functions, shown here in Table 1.

Table 1

REXX Function		Converts from
c2x			Character to hexadecimal
x2b			Hexadecimal to binary
x2c			Hexadecimal to character
x2d			Hexadecimal to decimal

The Building Blocks

Part one walked through a single IDCAMS formatted dump output record, and demonstrated how the first 20 bytes mapped to the documented SMF record header format and their respective translated values as shown in Figure 1.

The first article also showed how each field needed to be manually translated according to its data format (e.g. binary, packed, EBCDIC, etc.). Manual translation may be tolerable for a few records here and there but moving forward, you’ll need a means to automate these translations in order to analyze SMF data in bulk. Let’s take a closer look at some of the critical REXX building blocks you'll need to perform these translation tasks.

  • OFFSET(documented_offset)

Because the IDCAMS PRINT utility doesn’t include the record length and segment descriptor fields in its output, what appears at offset 0 in the IDCAMS formatted dump is actually defined at offset 4 per the defined SMF record header. So when performing a manual translation, one always needs to be cognizant of this 4-byte difference between the documented and "actual" individual offsets and account for it accordingly for each calculation.

From a coding and maintenance perspective, it would make the code much cleaner (and your lives much easier) if there were a function that just handled these offset differences without constantly having to worry about the "offset math" each time you wanted to examine a particular field. The REXX OFFSET() function does this:

 Function: OFFSET
 Input: Field offset (decimal) per SMF Reference (SA22-7630, Chapter 14)
 Output: Input offset minus three
   To get the correct offset into the SMF input line, subtract three
   bytes. These three bytes consist of:
   2 bytes, to account for RDW not being present
   1 byte, because in Rexx, indices begin at position 1, not zero
offset: procedure
  arg this_offset
  return (this_offset-3)

As you can see, the actual code is relatively simple but this abstraction will prevent trouble down the road.

  • SMF Data Format

SMF record fields come in a variety of different data formats such as binary, packed, EBCDIC, etc. At least one function is needed for each type of format you might encounter as well for different output formats you might want to work with.

  • BINARY_D (dump_line, offset, documented_field_length)

The binary_d() function takes a single formatted dump output record and extracts the field that’s documented as being BINARY, beginning at a particular offset (per the OFFSET() function) for the specified documented length in bytes. It also returns the extracted field in decimal format.

 Function: Binary_d
 Returns : Decimal
binary_d: procedure expose __.
  parse arg @dumpline,@offset,@field_length
  this_field = substr(@dumpline,@offset,@field_length)
  translated_field = x2d(c2x(this_field))
  return (translated_field)

You'll probably use the binary_d() function more often than not when displaying a BINARY field because we're a decimal-based society. However, there might be occasions where you want to display a BINARY field in some other output format.

  • BINARY_X (dump_line, offset, documented_field_length)

There might be times when you would like to work with the hexadecimal representation of a field. The binary_x() function is similar to the binary_d() function except that the extracted field is returned in hexadecimal format.

 Function: Binary_x
 Returns : Hexadecimal
binary_x: procedure expose __.
  parse arg @dumpline,@offset,@field_length
  this_field = substr(@dumpline,@offset,@field_length)
  translated_field = c2x(this_field)
  return (translated_field)
  • BINARY_B (dump_line, offset, documented_field_length)

Similar to the binary_d() and binary_x() functions, the binary_b() function returns the extracted field in binary bit vector format. For example, translating the SMFxFLG field of the standard SMF header is one instance where you might use the binary_b() function.

 Function: Binary_b                                                          
 Returns : Binary                                                               
binary_b: procedure expose __.                                                  
  parse arg @dumpline,@offset,@field_length                                                 
  this_field = substr(@dumpline,@offset,@field_length)                                              
  translated_field = x2b(c2x(this_field))                                                                
  return (translated_field)

George Ng is a senior certified I/T managing consultant for IBM Systems and Technology Group Lab Services at IBM Poughkeepsie. His areas of focus include z/OS Parallel Sysplex, High Availability and Performance.

Like what you just read? To receive technical tips and articles directly in your inbox twice per month, sign up for the EXTRA e-newsletter here.

comments powered by Disqus



2019 Solutions Edition

A Comprehensive Online Buyer's Guide to Solutions, Services and Education.

A Beginner's Guide to the REXX Programming Language on z/OS

Reading and Writing Files in the REXX programming language on z/OS.


Application Management is Important to the Entire Process


Application Testing: Giving Users What They Need

IBM Systems Magazine Subscribe Box Read Now Link Subscribe Now Link iPad App Google Play Store
Mainframe News Sign Up Today! Past News Letters