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:
Additional optional parameters:
-
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
...
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:
What Applications Benefit Most?
pySDSF automation is particularly valuable for:
These workloads benefit from pySDSF because they require repeatable, automated access to SDSF data that would otherwise require manual panel navigation.
Key Takeaways
For detailed API documentation and reference materials, pySDSF includes comprehensive documentation in the installation directory:
/usr/lpp/sdsf/python/doc/
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.