Python

 View Only

Introducing pySDSF: Managing z/OS SDSF Workloads with Python

By Kiarash Alirezaei posted 06/22/26 03:09 PM

  

Overview 

pySDSF is a Python interface for IBM z/OS System Display and Search Facility (SDSF) that enables programmatic access to system operational data. Included with SDSF starting in z/OS 3.2, pySDSF allows Python scripts to retrieve job information, browse job output, inspect system logs, and perform authorized actions - capabilities traditionally accessed only through interactive SDSF panels. 

This blog demonstrates practical pySDSF use cases for automating routine operational tasks on z/OS, including job monitoring, output inspection, and system log analysis. Real-world applications that benefit from pySDSF automation include operational monitoring scripts, job completion tracking, log analysis for troubleshooting, and integration of z/OS operational data into Python-based dashboards or alerting systems. 

Prerequisites and Installation 

Environment Requirements 

pySDSF requires: 

  • z/OS SDSF 3.2  

  • IBM Open Enterprise SDK for Python 3.13.x  

  • Proper SDSF authorization (SAF resources) 

Installation Steps 

  1. Verify Python version: 

python --version # Should show: IBM Open Enterprise SDK for Python 3.13.x  

  1. Install pySDSF: 

pip install /usr/lpp/sdsf/python/dist/pysdsf-3.2-cp313-none-any.whl 

  1. Verify installation: 

    pip3 list | grep pysdsf 
    # You should see: 
    # pysdsf      3.2 
      
    # For detailed information, you can also run: 
    pip show pysdsf 


Verifying the Connection
 

pySDSF includes sample scripts in the installation directory that demonstrate common use cases. These samples are located at: <site-packages-path>/pysdsf/samples/ 

 
Before performing operational queries, verify pySDSF connectivity and security context by running the provided who_sample.py: 

python3 -m pysdsf.samples.who_sample 

This sample calls connection.who() to retrieve session information:

from pysdsf import Connection 
from pysdsf.isfexception import ISFException 
  
connection = Connection() 

try: 
    who_result = connection.who() 
    for who_row in who_result: 
        print(who_row) 
except ISFException as e: 
    print(e) 
finally: 
    connection.close() 


Sample output:

ISF444I USERID=IBMUSER 
ISF444I PROC= 
ISF444I TERMINAL= 
ISF444I GRPINDEX=1 
ISF444I GRPNAME=ISFSPROG 
ISF444I MVS=z/OS 03.02.00 
ISF444I JES=z/OS 3.2 
ISF444I SDSF=HQX77F0 
ISF444I ISPF=N/A 
ISF444I RMF/DA=HSF 
ISF444I SERVER=YES 
ISF444I SERVERNAME=SDSF 
ISF444I JESNAME=JES2 
ISF444I MEMBER=IPO1 
ISF444I JESTYPE=JES2 
ISF444I SYSNAME=TVT5073 
ISF444I SYSPLEX=PLEX1 
ISF444I COMM=NOTAVAIL 
ISF444I COMMX=ENABLED 
ISF444I JOBID=STC05574 
ISF444I XCFGROUP=TVT5073 
ISF444I SESSID=1 
ISF444I NUMSESS=1 
ISF444I PROFILE=NONE 
ISF767I Request completed. 

This confirms: 

  • Your user identity (USERID=IBMUSER) 

  • SDSF security group (GRPNAME=ISFSPROG) used for authorization 

  • System context (SYSNAME=TVT5073, SYSPLEX=PLEX1) 

  • SDSF server availability (SERVER=YES) 

 

Listing Jobs

Run the provided status_sample.py to see job listing in action: 

python3 -m pysdsf.samples.status_sample 

This sample retrieves job information using  connection.status_of_jobs() with filters: 

from pysdsf import Connection 
from pysdsf.isfexception import ISFException 
  
connection = Connection() 
  
try: 
    status_result = connection.status_of_jobs( 
        prefix='SDSF*', 
        owner='*' 
    ) 

    if len(status_result): 
        print('Job_Name Job_ID     Queue') 
        for row in status_result: 
            print(f'{row["JNAME"].ljust(8)} {row["JOBID"].ljust(8)} {row["QUEUE"].ljust(10)}') 
    else: 
        print('Jobs with prefix SDSF* not found') 

except ISFException as e: 
    print(f'Error occurred response is {e}') 
finally: 
    connection.close() 

Sample Output: 

Job_Name    Job_ID         Queue 
SDSF             STC05491   EXECUTION 
SDSFAUX     STC05519   EXECUTION 
SDSF             STC05410   PRINT 

Parameters used in this sample: 

  • prefix: Filters jobs by name prefix (e.g., SDSF* returns jobs starting with SDSF) 

  • owner: Job owner filter 

Additional optional parameters: 

  • columns: limits returned fields for performance (e.g., columns=['JNAME', 'JOBID', 'RETCODE']) 

  • filter: Applies additional filtering criteria (e.g., filter=["queue eq print"] to show only print queue jobs) 

  • sort: Sorts results by specified columns (e.g., sort=["jname a", "jobid d"] for ascending job name, descending job ID) 

Performance Best Practice: While filter and sort are powerful, it is recommended to use the prefix and owner parameters first whenever possible, as they are applied earlier in the SDSF data retrieval process and can reduce the amount of data processed. For a complete list of available columns and supported filters for each SDSF panel, refer to the SDSF documentation.

Browsing Job Output 

Run the provided browse_sample.py to access job spool data sets: 

python3 -m pysdsf.samples.browse_sample 

This sample uses connection.active_users() to find jobs, then calls browse()to retrieve output: 

from pysdsf import Connection  
from pysdsf.isfexception import ISFException 

connection = Connection() 
options = { 'prefix': 'SDSFAUX*', 'owner': '*' } 

try:  
   da_result = connection.active_users(**options) 

   if len(da_result): 
      for da_row in da_result: 
         print(f'Browse result for {da_row["JNAME"]}({da_row["JOBID"]})') 
         browse_result = da_result.browse(da_row, **options) 
         if browse_result: 
            for line in browse_result: 
                print(line) 
         else: 
            print('Nothing to browse') 
   else: 
      print('Jobs with prefix SDSFAUX* not found')    
  
except ISFException as e:  
   print(e) 
finally:  
   connection.close() 

Sample Output: 

Browse result for SDSFAUX(STC05519) 
1                    J E S 2  J O B  L O G  --  S Y S T E M  I P O 1  --  N O D E  T V T 5 0 7 3 
0 
15.15.34 STC05519 ---- WEDNESDAY, 06 MAY 2026 ---- 
15.15.34 STC05519  IEF695I START SDSFAUX  WITH JOBNAME SDSFAUX  IS ASSIGNED TO USER IBMUSER , GROUP OMVS 
15.15.34 STC05519  $HASP373 SDSFAUX  STARTED 
15.15.34 STC05519  HSF0001I Server initializing 
15.15.34 STC05519  HSF0002I Server initialization complete 
15.15.34 STC05519  ISF540I Server SDSF assigned as default server. 
15.15.34 STC05519  ISF433I Server SDSF XCF connection established as server "HSF     HSFIXC". 
15.15.34 STC05519  ISF442I Server SDSF XCF communications ready. 
         1 //SDSFAUX  JOB MSGLEVEL=1                                               STC05519 
         2 //SDSFAUX  EXEC SDSFAUX 
... 

This demonstrates programmatic access to job logs, JES messages, and spool output - data typically viewed manually through SDSF panels.

Reading the System Log 

Run the provided syslog_sample.py to query SYSLOG with time-based filtering: 

python3 -m pysdsf.samples.syslog_sample  

This sample uses connection.read_syslog() to retrieve system log records for a specific time window: 

import datetime 
from pysdsf import Connection 
from pysdsf.isfexception import ISFException 
  
connection = Connection() 

# Define time window (last hour) 
today = datetime.datetime.now() 
an_hour_ago = today - datetime.timedelta(hours=1) 
  
start_date = an_hour_ago.strftime("%m/%d/%Y") 
start_time = an_hour_ago.strftime("%H:%M:%S") 
stop_date = today.strftime("%m/%d/%Y") 
stop_time = today.strftime("%H:%M:%S") 

try: 
    syslog_result = connection.read_syslog( 
        start_date=start_date, 
        start_time=start_time, 
        stop_date=stop_date, 
        stop_time=stop_time, 
        response_limit=1000 
    ) 
    print("Syslog records follow ...") 
    for row in syslog_result: 
        print(row) 

except ISFException as e: 
    print(e) 
finally: 
    connection.close() 

 

Sample Output:

N 4000000 TVT5073  26131 13:30:14.72 STC05586 00000090  $HASP373 BPXAS    STARTED 
N 0000000 TVT5073  26131 13:30:14.72 STC05586 00000290  BPXP024I BPXAS INITIATOR STARTED ON BEHALF OF JOB SSHD4 RUNNING IN ASID 
S                                                       0048 
N 0200000 TVT5073  26131 13:30:14.81 STC05587 00000281  $HASP100 BPXAS    ON STCINRDR 
N 4000000 TVT5073  26131 13:30:14.82 STC05587 00000090  $HASP373 BPXAS    STARTED 
... 

Use cases include: 

  • Monitoring for specific message IDs 

  • Tracking system events during a time window 

  • Automated log analysis for troubleshooting  

Example use case: A Python script could scan SYSLOG for $HASP373 messages to detect when a critical batch job starts, then send an alert or update a dashboard. Similarly, monitoring for HZS* messages allows automated detection of Health Checker warnings without manual SYSLOG review. 

# Example: Filter syslog results for specific message IDs 

for row in syslog_result:  
   if '$HASP373' in row or 'HZS' in row:  
      print(f"Alert: {row}") 

Inspecting Job Steps 

While pySDSF includes a job_step_sample.py, it uses a placeholder job name (MYJOB) that may not exist on your system. Here's how to retrieve step-level execution details using the JS action with a real target: 

from pysdsf import Connection  
from pysdsf.isfexception import ISFException 
connection = Connection() 

try: # Find active jobs matching a known prefix da_result = connection.active_users(prefix='SDSFAUX*', owner='*') 
    if len(da_result): 
        for da_row in da_result: 
            print(f'Job step details for {da_row["JNAME"]}({da_row["JOBID"]})') 
            # Request job step information 
            js_result = da_result.action('JS', da_row,  
                action_columns=['STEPNAME', 'PGMNAME', 'RETCODE', 'STEPNUM'])        
            if js_result: 
                for js_row in js_result: 
                    print(f"  Step: {js_row['STEPNAME']}, " 
                        f"Program: {js_row['PGMNAME']}, " 
                        f"RC: {js_row['RETCODE']}, " 
                        f"Step#: {js_row['STEPNUM']}") 
    else: 
        print("No matching jobs found") 
  
except ISFException as e:  
    print(e)  
finally:  
    connection.close() 

Sample Output:

Job step details for SDSFAUX(STC05519) 
  Step: SDSFAUX, Program: HSFSRV00, RC: ACTIVE, Step#: 1 

This provides programmatic access to: 

  • Step names and program names 

  • Return codes or active status (ACTIVE for running steps) 

  • Step numbers 

  • Additional timing information available via columns like ELAPSED, CPUTIME, SRBTIME 

What Applications Benefit Most? 

pySDSF automation is particularly valuable for: 

  • Operational monitoring scripts - Track job completion, detect failures, alert on specific conditions 

  • Log analysis and troubleshooting - Search SYSLOG for patterns, extract relevant time windows 

  • Integration with Python dashboards  - Feed z/OS operational data into monitoring tools or web interfaces 

  • Batch job orchestration - Check job status before triggering dependent workflows 

  • Compliance and auditing - Programmatically collect job execution records for reporting 

These workloads benefit from pySDSF because they require repeatable, automated access to SDSF data that would otherwise require manual panel navigation. 

Key Takeaways 

  • Authorization is enforced through the same SAF resources used by interactive SDSF. If you can use SDSF interactively, you likely have the necessary authorization for pySDSF. 

  • Core capabilities include: 

    • Job listing with status_of_jobs() or active_users() 

    • Output browsing with browse() 

    • System log reading with read_syslog() 

    • Action invocation with action() (e.g., JS for job steps) 

  • Filtering and column selection improve performance by limiting data retrieval. 

  • Sample scripts in the pysdsf/samples directory provide working examples for common tasks. Use pip show pysdsf to locate the samples directory. 

Additional Resources 

For detailed API documentation and reference materials, pySDSF includes comprehensive documentation in the installation directory: 

/usr/lpp/sdsf/python/doc/  

This directory contains: 

  • README - Installation and setup guide 

  • pySDSF.md - Complete API documentation with function descriptions, parameters, and examples 

  • ref/ - Additional reference materials 

 

pySDSF bridges the gap between z/OS operational data and Python automation, enabling scripts to perform tasks that previously required interactive SDSF sessions. By combining pySDSF with Python's rich ecosystem of libraries for data analysis, web frameworks, and automation tools, you can build sophisticated operational monitoring and management solutions on z/OS. Start with the sample scripts provided in this blog, then explore the comprehensive documentation in /usr/lpp/sdsf/python/doc/ to unlock the full potential of pySDSF for your operational needs. 

Want to learn more about using Python on z/OS? Visit our Python Portal for a convenient way to access more resources.

0 comments
26 views

Permalink