IBM MTM 2019: Part Three – Challenge #15

Hello Hello Hello

Today I’m doing the very last challenge of the IBM Master the Mainframe 2019 contest. It has been a long 4 months and we’ve finally reached the finish line.Now let’s take some time to finish this exercise.

Originally I wrote “exercise” wrong, but then I Googled it and corrected it. JUST. FOR. YOU. Isn’t that lovely? (heart emoji thing) Also, the WordPress spelling corrector underlined that word red and it triggered me very hard. You see, UX helps!

So, just to be able to finish before the 31st of December I’ll do a minimum viable product approach. That means I’ll do the absolute minimum to pass (i hope).

Also my apologies to everyone. I have 20 to 30 comments waiting for help and a ton of e-mails still waiting for a reply. I can’t keep up with the demand! Work, holidays, family and partying is taking up most of my time. Goodluck to everyone!

Learning and using z/OS creatively

IBM Master the Mainframe Part Three – Challenge #15

Start the Final Challenge

Let’s start by getting the required data sets. We can do this by issuing tso submit ‘zos.public.jcl(p3ch15)’ from the ISPF Primary Option Menu.

The first time you do this it will allocate new data sets. The second time you do this it will delete and reset some data sets. BE WARNED!

It made the following data sets:

  • ch15.clist
  • ch15.output

It also wrote a timestamp into p3.output(#15) and created REXXJCL member in our JCL data set.

System Activity Utility

From the ISPF Command Shell Panel (=6) I’ll issue the command ex ch15(get) to execute our challenge 15 code.

I’ll enter to select ‘Report specific message identifier found in SYSLOG’.

If prompted for a message id enter ich408i.

This is the result.

Solving this challenge

Don’t take my word for it. Don’t automatically assume I’m right. I don’t exactly have an answer sheet 😉

But what needs to be done?

  • The challenge is for you to enhance a system utility which generates point-in-time system activity reports.
  • At least 1 report you write must demonstrate ability to parse SYSLOG records.
  • Information requested has options 1-6 constructed, option 7 is blank.

So does this mean that I need to make option 7? And make it output whatever I want/can? There needs to be at least 1 report that parses SYSLOG records.

Is this the absolute minimum? I assume so. Great!

Step 1: REXXJCL

I just noticed the ID needs to be filled in in our Z#####.JCL(REXXJCL). I’ll do that first. GETSTRG does not exist in my CH15.CLIST data set. Do I need to create that member? Do I even need to do this? (I didn’t)

Warning: don’t do this just because I do!

Step 2: Explore CH15.CLIST

For the most part I’ll let you figure this out yourself. I’ll only write about the most interesting parts.

These are the challenge files we’re working with.

When we do ex ch15(get) we actually execute this rexx code.

So… IBM has left us with a few options and ideas. We can just code the ones they suggest or we can invent a new option at option 7.

For the MVP principle, I’ll delete 3 options and only do one, the fourth one. As I’m part of the learner program I have about 9 months more to expand. My apologies to the people that thought I would make something impressive! 

I just want to provide an example during the last days the students have available.

Step 3: The Plan

The easiest one in my opinion is getting the TSO logons, unsuccessfull or successfull. ICH70001I is the code that gets logged when a user has logged on. Shortly after that code, the username is displayed along with some timestamps.

I just need to grab those entries and print them to the screen. I can basically use the code of report 1, remove the input prompts, sanitize the data and then it should be ok!

Let me test my theory.

My theory is correct! I’ll delete the other options and make it clear to IBM which option they need to pick.

I have removed the excess options and added the exec ch15(custom) command. Now I’ll go ahead and code my custom option. My custom option will also use the custom file in the clist data set.

Step 4: Coding

Unfortunately, I’m not allowed to share my code. But you should be fine on your own! I have used code bits from https://www.tutorialspoint.com/rexx/rexx_parsing.htm and https://www.rosettacode.org/wiki/Remove_duplicate_elements#REXX to write the solution.

My result

This is the menu that is now generated.

Then after that we get the following output:

So this is an unique list of all the users that have logged on. I’m happy with my MVP approach. I believe these are the logons from today? I’m not 100% sure.

Have I missed something? What have you come up with?

I feel like I have though. Although, I have at least 1 report that demonstrates ability to parse SYSLOG records and I have enhanced a system utility. Is this enough?

IBM MTM 2019: Part Three – Challenge #14

Hello Hello!

This is the “last” challenge of IBM’s Master the Mainframe 2019 challenge! I can’t believe I already made 30 blogposts in the last 4 months. Time goes by so fast!

The fifteenth challenge requires every individual contestant to come up with something unique. I won’t be much of help with the fifteenth challenge but at least you’ll have an example. I hope I don’t set the bar too low or something haha.

This challenge looks simple, perfect finishing touch to the part 3 challenge series in my opinion.

Hi California 😉

Tip by Kevin Durant: your output is going to be different than mine.

Tip by Felipe Fontes: S0W1, 0 is ZERO, not the letter O.

z/OS System Log

IBM Master the Mainframe Part Three – Challenge #14

Get and execute LOGLOOK REXX code

In my REXX data set I’ll create a new member called loglook. In there I’ll copy ‘zos.mtm2019.public.rexx(loglook)’.

I’ll go back using F3 and execute the script by using the line command ex next to our newly created loglook data set member.

What is the contest system name?

I guess SYS1? But last challenge it said in the output: “Column SYSNAME.1 has the value: S0W1”. So wouldn’t it be S0W1 then?

Revisit the SYSLOG and gather needed information

Aye chef! From anywhere I’ll enter =sd;log. I’ll enter the primary command SYM to list the system symbolics.

The system ID is synonomous with sysname, don’t forget it. I’ll go back using F3. Now, I’ll just enter top to go to the top

And then I’ll enter f z50087 to find log entries made by me. If I don’t find any, I’ll refresh using F5.

I have found some! Now what to do with it?

Modify LOGLOOK REXX code

I have to what?! Kidding! We need to make the following modifications:

  • Provide the correct system ID
  • Provide a search string which needs to be your ID

Ok the system ID we have remembered from last time and the search string is our IBM id. This should be pretty straight forward then? Let me see.

This part of the code has some variables. Which ones do we need to change? Hmm… I think I know which ones to change. I’ll do it.

Successful execution has records containing:

  1. log date
  2. log time
  3. message text where message text includes your id

Let’s take a look at my P3.OUTPUT(#14).

Looks good! On to Part 3 Challenge 15!

IBM MTM 2019: Part Three – Challenge #13

Hello!

Let’s get our hands dirty and modify some REXX code! This time we’re looking at some system variables and we’ll print them to a data set member!

PS: I’m not sure if I will make the student’s deadline this year. The learning system deadline is the 9th of september 2020 or something. But I’ll try my best!

Advanced REXX Programming Interface – field names and values from SYS

IBM Master the Mainframe Part Three – Challenge #13

Explore SDSF real time system information

I’ll leave this part up to you 😉

Copy, review, and execute REXX code that gathers system information

In my REXX data set I’ll create a new member called zperf. I assume that stands for IBM Z Performance? In edit mode I’ll copy ‘zos.mtm2019.public.rexx(zperf)’ into it. I’ll also enter the primary command hilite rexx to have some syntax highlighting in the editor.

Now I’ll return to the data set member overview and issue the line command ex next to the zperf member to execute the REXX.

It should write a message to our P3.OUTPUT(#13) data set member.

It did. Nice!

Modify REXX code and observe differences

We need to do the following:

  1. Comment lines 9, 10, and 11
  2. Uncomment lines 13, 14, 15, and 16
  3. Uncomment line 36 – Comment line 36 line before creating final report
  4. Save and execute to observe differences

No weird stuff, we need to remember to comment line 36 before creating the final report. I hope the indentation at line 36 is still ok. So, I’ll go back and ex the zperf member again and check the output.

Wooh, a lot of red text. My P3.OUTPUT(#13) has not changed though.

I’ll keep a list of the variables here so I can use them in the code later.

Column SYSNAME.1 has the value: S0W1
Column TOKEN.1 has the value: 4TwSNj...bCmGHGw
Column SYSLEVEL.1 has the value: z/OS 02.03.00 HBB77B0
Column CPUPR.1 has the value: 54
Column SIO.1 has the value: 650
Column AUXPCT.1 has the value: 0
Column CSAPCT.1 has the value: 6
Column SQAPCT.1 has the value: 30
Column ECSAPCT.1 has the value: 13
Column ESQAPCT.1 has the value: 71
Column UIC.1 has the value: 65535
Column SPOOLPCT.1 has the value: 22
Column CADSPCT.1 has the value: 48
Column PAGERATE.1 has the value: 0
Column REAL.1 has the value: 2016727
Column REALAFC.1 has the value: 911297
Column REALAFCB.1 has the value: 2479
Column FIXPCT.1 has the value: 4
Column FIXBPCT.1 has the value: 1
Column MAXASID.1 has the value: 2495
Column FREEASID.1 has the value: 2315
Column BADASID.1 has the value: 0
Column STCNUM.1 has the value: 83
Column TSUNUM.1 has the value: 59
Column JOBNUM.1 has the value: 0
Column WTORNUM.1 has the value: 3
Column SYSPLEX.1 has the value: SVSCPLEX
Column LPAR.1 has the value:
Column VMUSER.1 has the value: DGBGMDU
Column JESNAME.1 has the value: JES2
Column JESNODE.1 has the value: SVSCJES2
Column SMF.1 has the value: S0W1
Column IPLVOL.1 has the value: VIMVSB
Column IPLUNIT.1 has the value: 1000
Column IPLDATE.1 has the value: 2019.342 13:24:10
Column IPLTYPE.1 has the value: COLD
Column IPLDAYS.1 has the value: 4
Column LOADPARM.1 has the value: 0CE3W1M1
Column CVTVERID.1 has the value:
Column LOADDSN.1 has the value: SYS1.IPLPARM
Column LOADUNIT.1 has the value: 0CE3
Column IEASYS.1 has the value: (00,LV,SV,VN)
Column IEASYM.1 has the value: (W1,SV,VN)
Column GRS.1 has the value: RING
Column HWNAME.1 has the value: VM-TOKEN
Column CPC.1 has the value: 003906.M04.IBM.02.0000000F1DF7
Column MSU.1 has the value: 10012
Column SYSMSU.1 has the value: 236
Column AVGMSU.1 has the value: 5
Column CPUNUM.1 has the value: 2
Column ZAAPNUM.1 has the value: 0
Column ZIIPNUM.1 has the value: 0
Column OSCONFIG.1 has the value: MVS
Column EDT.1 has the value: 00
Column NUCLST.1 has the value: SV
Column IEANUC.1 has the value: 01
Column IODFDSN.1 has the value: SYS1.IODF00
Column IODFDATE.1 has the value: 2017.177 14:56:10
Column CATDSN.1 has the value: MASTERV.CATALOG
Column CATVOL.1 has the value: VPMVSB
Column MLA.1 has the value: 1
Column CATTYPE.1 has the value: ICF
Column NETID.1 has the value: USASDV02
Column SSCP.1 has the value: USASDV02.MVR23GA
Column STATDATE.1 has the value: 2019.346 12:18:00
Column IPLCUNIT.1 has the value: 1000
Column IODFUNIT.1 has the value: 0CE3
Column IODFCUNIT.1 has the value: 0CE3

Modify REXX code to produce customize performance report

So the “Description of the challenge ZPERF REXX code” paragraph by IBM tell us what every function does in this REXX script.

We need to include the following information in our report:

  1. CPU percent busy for the system
  2. High unreferenced interval count
  3. Real storage available frame count
  4. Number of active started tasks
  5. Number of active TSO users
  6. Number of active batch jobs

And you probably guessed it, I’m doing the bare minimum! Note to my future employers, this is not my work attitude 😉

We know the following: “The information above is available from the SDSF SYS column fields.”. Now then, let’s just figure out how we echo each piece and finish this challenge.

So when we get to the variable name we want we need to execute a write function. Easy. I’ll figure out the 6 variables we need and then create 6 copies of the write_variablename function. Not the way I like to write it, but hey, bare minimum. For example, if I need MSU i’ll change then nop to then call write_msu and create a function called write_msu. Don’t forget you can search the text using the primary command f <query>.

How will I find out these variables? Easy! Google! I search for “High unreferenced interval count mainframe” and I can find an exact match on https://www.ibm.com/support/knowledgecenter/en/SSLTBW_2.3.0/com.ibm.zos.v2r3.isfa600/isfa600ug_isfjvsys.htm showing the variable title. This page actually has all of them.

My output looks good! On to challenge 14!