How to use UNIX commands in SAS code to read SAS logs

Similar documents
Electricity Forecasting Full Circle

A Macro To Generate a Study Report Hany Aboutaleb, Biogen Idec, Cambridge, MA

Using GSUBMIT command to customize the interface in SAS Xin Wang, Fountain Medical Technology Co., ltd, Nanjing, China

A Macro that can Search and Replace String in your SAS Programs

Paper CC16. William E Benjamin Jr, Owl Computer Consultancy LLC, Phoenix, AZ

A SAS Macro for Producing Benchmarks for Interpreting School Effect Sizes

Program Validation: Logging the Log

Text Generational Data Sets (Text GDS)

Use That SAP to Write Your Code Sandra Minjoe, Genentech, Inc., South San Francisco, CA

A Macro to Create Program Inventory for Analysis Data Reviewer s Guide Xianhua (Allen) Zeng, PAREXEL International, Shanghai, China

A SAS Macro Utility to Modify and Validate RTF Outputs for Regional Analyses Jagan Mohan Achi, PPD, Austin, TX Joshua N. Winters, PPD, Rochester, NY

Base and Advance SAS

Using DDE with Microsoft Excel and SAS to Collect Data from Hundreds of Users

Useful Tips When Deploying SAS Code in a Production Environment

Debugging. Where to start? John Ladds, SAS Technology Center, Statistics Canada.

Write SAS Code to Generate Another SAS Program A Dynamic Way to Get Your Data into SAS

How a Code-Checking Algorithm Can Prevent Errors

SAS CURRICULUM. BASE SAS Introduction

Dictionary.coumns is your friend while appending or moving data

So Much Data, So Little Time: Splitting Datasets For More Efficient Run Times and Meeting FDA Submission Guidelines

My SAS Grid Scheduler

/* CalcESLs.sas */ /* */ /* Created 02 January 2006 by Sarah Gilman */ /* report errors to

Logging the Log Magic: Pulling the Rabbit out of the Hat

Check Please: An Automated Approach to Log Checking

A Macro to Keep Titles and Footnotes in One Place

Chasing the log file while running the SAS program

The Demystification of a Great Deal of Files

PharmaSUG Paper AD06

Automate Secure Transfers with SAS and PSFTP

SAS 101. Based on Learning SAS by Example: A Programmer s Guide Chapter 21, 22, & 23. By Tasha Chapman, Oregon Health Authority

Document and Enhance Your SAS Code, Data Sets, and Catalogs with SAS Functions, Macros, and SAS Metadata. Louise S. Hadden. Abt Associates Inc.

Macros are a block of code that can be executed/called on demand

PharmaSUG Paper PO12

ABSTRACT INTRODUCTION MACRO. Paper RF

Cutting the SAS LOG down to size Malachy J. Foley, University of North Carolina at Chapel Hill, NC

Acquisition and Management of Market Data for SAS Risk Dimensions

Untangling and Reformatting NT PerfMon Data to Load a UNIX SAS Database With a Software-Intelligent Data-Adaptive Application

TLF Management Tools: SAS programs to help in managing large number of TLFs. Eduard Joseph Siquioco, PPD, Manila, Philippines

PDF Multi-Level Bookmarks via SAS

Reading in Data Directly from Microsoft Word Questionnaire Forms

Demystifying Inherited Programs

Your Own SAS Macros Are as Powerful as You Are Ingenious

Macro Method to use Google Maps and SAS to Geocode a Location by Name or Address

Building Sequential Programs for a Routine Task with Five SAS Techniques

Someone Changed My SAS Visual Analytics Report! How an Automated Version Control Process Can Rescue Your Report and Save Your Sanity

SUGI 29 Data Warehousing, Management and Quality

Integrating Large Datasets from Multiple Sources Calgary SAS Users Group (CSUG)

Avoiding Macros in SAS. Fareeza Khurshed Yiye Zeng

SAS Viya 3.1 FAQ for Processing UTF-8 Data

PharmaSUG 2013 CC26 Automating the Labeling of X- Axis Sanjiv Ramalingam, Vertex Pharmaceuticals, Inc., Cambridge, MA

Moving Data and Results Between SAS and Excel. Harry Droogendyk Stratia Consulting Inc.

Taming a Spreadsheet Importation Monster

INTRODUCTION TO SAS HOW SAS WORKS READING RAW DATA INTO SAS

Implementing external file processing with no record delimiter via a metadata-driven approach

Clinical Data Visualization using TIBCO Spotfire and SAS

DSCI 325: Handout 15 Introduction to SAS Macro Programming Spring 2017

Missing Pages Report. David Gray, PPD, Austin, TX Zhuo Chen, PPD, Austin, TX

What's the Difference? Using the PROC COMPARE to find out.

Purchase this book at

A Tutorial on the SAS Macro Language

HOW TO EFFECTIVELY DEAL WITH HARDCODING AND CDISC CONTROLLED TERMINOLOGY IN CLINICAL STUDIES

Identifying Duplicate Variables in a SAS Data Set

Utilizing SAS for Cross- Report Verification in a Clinical Trials Setting

Leave Your Bad Code Behind: 50 Ways to Make Your SAS Code Execute More Efficiently.

Call: SAS BI Course Content:35-40hours

SAS CLINICAL SYLLABUS. DURATION: - 60 Hours

Using SAS to Control and Automate a Multi SAS Program Process Patrick Halpin, dunnhumby USA, Cincinnati, OH

The Output Bundle: A Solution for a Fully Documented Program Run

Extending the Scope of Custom Transformations

TASS Interfaces Open Question

Automated Checking Of Multiple Files Kathyayini Tappeta, Percept Pharma Services, Bridgewater, NJ

The Power of PROC SQL Techniques and SAS Dictionary Tables in Handling Data

AN INTRODUCTION TO MACRO VARIABLES AND MACRO PROGRAMS Mike Zdeb, School of Public Health

Application Interface for executing a batch of SAS Programs and Checking Logs Sneha Sarmukadam, inventiv Health Clinical, Pune, India

Developing Data-Driven SAS Programs Using Proc Contents

Using UNIX Shell Scripting to Enhance Your SAS Programming Experience

A Macro for Systematic Treatment of Special Values in Weight of Evidence Variable Transformation Chaoxian Cai, Automated Financial Systems, Exton, PA

Guidelines for Organizing SAS Code and Project Files

ABSTRACT INTRODUCTION WORK FLOW AND PROGRAM SETUP

Make SAS Enterprise Guide Your Own. John Ladds Statistics Canada Paper

Data Quality Review for Missing Values and Outliers

Principles of Automation

Run your reports through that last loop to standardize the presentation attributes

A Time Saver for All: A SAS Toolbox Philip Jou, Baylor University, Waco, TX

Using an ICPSR set-up file to create a SAS dataset

%MAKE_IT_COUNT: An Example Macro for Dynamic Table Programming Britney Gilbert, Juniper Tree Consulting, Porter, Oklahoma

Let SAS Help You Easily Find and Access Your Folders and Files

What Do You Mean My CSV Doesn t Match My SAS Dataset?

A Practical and Efficient Approach in Generating AE (Adverse Events) Tables within a Clinical Study Environment

IT 433 Final Exam. June 9, 2014

Using SAS to Control the Post Processing of Microsoft Documents Nat Wooding, J. Sargeant Reynolds Community College, Richmond, VA

This Too Shall Pass: Passing Simple and Complex Parameters In and Out of Macros

SAS Programs Read the raw data

SAS 9 Programming Enhancements Marje Fecht, Prowerk Consulting Ltd Mississauga, Ontario, Canada

Prove QC Quality Create SAS Datasets from RTF Files Honghua Chen, OCKHAM, Cary, NC

SURVIVING THE SAS MACRO JUNGLE BY USING YOUR OWN PROGRAMMING TOOLKIT

Geocoding Crashes in Limbo Carol Martell and Daniel Levitt Highway Safety Research Center, Chapel Hill, NC

Bryan K. Beverly, UTA/DigitalNet

A Macro that Creates U.S Census Tracts Keyhole Markup Language Files for Google Map Use

Better Metadata Through SAS II: %SYSFUNC, PROC DATASETS, and Dictionary Tables

Transcription:

SESUG Paper 030-2017 How to use UNIX commands in SAS code to read SAS logs James Willis, OptumInsight ABSTRACT Reading multiple logs at the end of a processing stream is tedious when the process runs on a UNIX platform. In UNIX, the logs must be individually viewed using a UNIX command like CAT or MORE or an application like ULTRA EDIT or the UNIX VI edit process. The UNIX options are tedious and time consuming for even skilled UNIX users. The risk of missing an important log message is significant. SAS batch programs running in UNIX can be chained together using include statements. When a long chain of programs is executed, and each program in the chain has its log printed separately, reviewing all of the logs from the process can be difficult. The process is definitely time consuming. Reading the logs using UNIX commands and SAS logic simplifies and speeds up the log verification process. "ERROR:", "WARNING:", "CONVERSION", "MISSING", "NOT FOUND" and all other messages can be located, ranked, written to a spreadsheet, and then the spreadsheet can be emailed to you. INTRODUCTION OptumInsight will execute SAS processes on a UNIX platform chaining multiple programs together so that they use one parameter file. Each program creates its own log file. One of my processes executes over 25 programs creating over 25 logs. I built a SAS program that reads each log created by the process so that I do not have to read each log manually. CREATE THE MACROS AND LIST OF LOGS TO BE READ The code uses macros and macro variables to allow for flexibility when programs are not run or extra programs are run during off cycles. Each macro is built by asking the question Is it code or is it data?. First you list the essential names of the log files that will be read: %LET loglist = 's050_prerun_format_testing', 's100_crm', 's100_online_reg', 's100_gym_activation', 's100_event_import', 's100_c360', 's100_icue_coaching', 's150_crm_to_lu_ayb', 's200_file_finder', 's300_lu_ayb_matching', 's400_qa_import_files', 's500_lu_ayb_indv_id', 'rs003_null_values_by_table', 'rs02_unspecified_counts', 'rs01_novu_report', 's600_copy_files_to_archive' ; The order of the names is not important except for the first and last names. My code lists the names in the order that they are included by the execution process. I use %GLOBAL statements for each macro defined in the code. 1

%let projekt = AYB_WEEKLY_LOGS_REVIEW; options lrecl=256 linesize=256 spool nomprint nosymbolgen nomlogic; Create a macro that contains the date that the logs were created on and have as their suffix. NamDt is used in the name of the log. RunDt is used in the name of the folder where the logs are stored. %let offset = 0; /*** change here ***/ data _null_ ; format namdt $7. f 8.; e = today() - %eval(&offset.) ; rundt = put(e,yymmddn8.) ; call symputx('rundt',rundt) ; f = "&sysdate."d - %eval(&offset.) ; namdt = put(f,date7.); call symputx('namdt',namdt) ; Create a macro that emails the results of the log review, created as a spreadsheet. The data null changes the UNIX location to the location of the excel file being emailed. My code creates an EXCEL.xlsx file. %macro emailit; %SYSEXEC %STR(cd /unix/folder/name/and/file/location;); filename mymail email subject="place your Email subject words here" TO="email.recipient@mail.address" attach=("&logdir./&projekt..xlsx" content_type="application/vnd.ms-excel" LRECL=9999) ; file mymail; put "The logs for &projekt. in &logdir. have been reviewed"; put "Check the attached file thoroughly to find any problems."; put "The attached file contains items that may be significant."; put 'The file also contains observation counts of datasets created during the process. '; %mend emailit; 2

CREATE THE MAIN LOGIC The logchek macro works for every file named in the &loglist. macro. Each line in the log is read, ranked, and classified. A line with chekline = 0 is not sent to the spreadsheet. The output file is sorted in rank order. %macro logchek; proc sql; drop table work.&logshrt.; quit; data work.&logshrt.; length row 8 chekline 8 source $ 30 message $ 25 logline $256; infile logchek linesize=256 recfm=v truncover pad noprint END=FINI; input logline $char256.; logline = strip(left(upcase(logline))); row = _n_; if row = 1 then do; chekline = 5; source = trim(left("&logpre.")); message = ' '; chekline = 0; source = trim(left("&logpre.")); message = ' '; if index(logline,'error!') > 0 and index(logline,'mprint') = 0 then do; message = " FOUND AN ERROR!" ; call symput(cat('err' strip(put(row,8.))),put(row,8.)); if index(logline,'error:') > 0 then do; message = " FOUND AN ERROR:" ; call symput(cat('err' strip(put(row,8.))),put(row,8.)); if index(logline,'warning:') > 0 then do; message = "FOUND A WARNING:"; chekline = 2; IF index(logline,'has NOT BEEN DROPPED') > 0 then chekline = 9; IF index(logline,'.data DOES NOT EXIST') > 0 then chekline = 7; if index(logline,'numeric') > 0 then do; message = "NUMERIC OR CHARACTER CONVERSION OCCURRED"; chekline = 2; if index(logline,'missing') > 0 then do; message = "FOUND A MISSING VALUE"; chekline = 3; /** division by 0 detected **/ if index(logline,'division') > 0 then do; message = "FOUND A DIVISION BY ZERO"; chekline = 4; if index(logline,'uninitialized') > 0 then do; 3

message = "UNINITIALIZED VARIABLE"; chekline = 5; if index(logline,'show stopper') > 0 and index(logline,'mprint') = 0 then do; message = " FOUND A SHOW STOPPER" ; if index(logline,'note') > 0 and index(logline,'stopped') > 0 then do; message = " FOUND AN ERROR MESSAGE" ; if index(logline,'=== =====>') > 0 and index(logline,'mprint') = 0 then do; message = " FOUND AN ARROW:" ; chekline = 2; if index(logline,'+put') > 0 then do; message = " " ; chekline = 0; if index(logline,'note') = 0 then do; if index(logline,' +') > 0 then chekline = 0; if index(logline,' +') > 0 then chekline = 0; if index(logline,'+run;') then chekline = 0; /*** print notes unless specifically not printed ***/ if index(logline,'note:') > 0 and chekline = 0 then do; if index(logline,'dropped') > 0 then chekline = 0; if index(logline,'procedure SQL') > 0 then chekline = 0; if index(logline,'the data set') > 0 then chekline = 9; if index(logline,'the DATA SET') > 0 then chekline = 9; if index(logline,'observations') > 0 then chekline = 9; if index(logline,'real TIME') > 0 then chekline = 0; if index(logline,'cpu TIME') > 0 then chekline = 0; if index(logline,'run;') > 0 then chekline = 0; if index(logline,'printto') > 0 then chekline = 0; if index(logline,'begins') > 0 then chekline = 0; if index(logline,'info') > 0 then chekline = 8; if index(logline,'nds') > 0 then chekline = 0; if index(logline,'mprint') > 0 then chekline = 0; if (index(logline,'table') > 0 and index(logline,'created,')) then chekline = 6; if index(logline,'symbolgen') > 0 then chekline = 0; if index(logline,%str('mprint(')) > 0 then chekline = 0; if index(logline,%str('(total PROCESS TIME)')) > 0 then chekline = 0; if index(logline,'the SAS SYSTEM') > 0 then chekline = 0; if index(logline,'note: The SAS System stopped') > 0 then if index(upcase(logline),'stopped') > 0 then do; message = "ERROR"; if index(upcase(logline),'error 180-322') > 0 then do; message = "ERROR"; 4

if chekline > 0 then do; output; return; proc sort data=work.&logshrt.; by chekline; %if "&logpre" = "&frstfil." %then %do; data work.logslist; set work.&logshrt.; % %else %do; proc append base=work.logslist data=work.&logshrt.; % %put &=export; %put "&logdir./&projekt..xlsx"; %if &export. = Y %then %do; %SYSEXEC %STR(cd &logdir.; rm &logdir./&projekt..xlsx); proc sort data=work.logslist; by chekline source; proc export data=work.logslist outfile = "&logdir./&projekt..xlsx" replace DBMS=xlsx; sheet=&projekt.; % %mend logchek; EXECUTE THE MAIN LOGIC FOR EACH LOG FILE The logset macro assigns the macro values to be used by the logchek macro then calls the logchek macro. %macro logset(log1=,export=,logshrt=); %let logpre = &log1.; /*** change here ***/ %let base = /location1/location2/location3; /*** change here ***/ %let pgm = /location4/location5/; /*** change here ***/ %let fldr = log_file_location_&rundt.; %let logdir = &base.&pgm.&fldr./location6; /*** change here ***/ 5

%let lognam = &logpre._&namdt.; %let export = &export.; %let logshrt = &logshrt.; %put "logchek lognam = &logdir./&lognam..log"; filename logchek clear; filename logchek "&logdir./&lognam..log"; %logchek; %mend logset; %let frstfil = s050_prerun_format_testing; /* first name in the loglist macro */ %let lstfil = s600_copy_files_to_archive; /* last name in the loglist macro */ /*** This will execute for as many log files as are in the "do" statement ***/ /*** All the log files have to be in the same UNIX folder location ***/ Each file named in the loglist macro variable is executed. When the file name in the loglist macro variable is the first log file or the last log file, special processing occurs. The email macro is called only after the last log file has been read. length log $ 100; exp = 'N'; do log = &loglist. ; logshrt = substr(log,1,4); Put "log = " log " and lstfil = &lstfil. "; if trim(left(upcase(log))) = trim(left(upcase("&lstfil."))) then exp = 'Y'; else exp = 'N'; call execute('%logset(log1=' log ',export=' exp ',logshrt=' logshrt ')'); if exp = 'Y' then do; call execute('%emailit'); SPREADSHEET EXAMPLE This picture shows an example of how warning messages in the log for the s100_icue_coaching program were ranked and output to the final spreadsheet. Ranking, showing the log source, log row and log message, allows me to quickly find issues that happened during processing. You know right away which program or programs in the process need to be reviewed. Display 1. Example of the spreadsheet that is created and emailed. 6

CONCLUSION Reading multiple logs at the end of a processing stream is tedious when the process runs on a UNIX platform. In UNIX, the logs must be individually viewed using a UNIX command like CAT or MORE or an application like ULTRA EDIT or the UNIX VI edit process. The UNIX options are tedious and time consuming for even skilled UNIX users. The risk of missing an important log message is significant. Using SAS to read log files, with an infile and an input statement, allows a programmer to read each line of a log, search for key words in each line, rank the key words found on each line, write out only the key findings, and email the key findings to one or more persons, makes a tedious, time consuming and risky chore, simple, quick and valuable. REFERENCES Robbins, Arnold. August 1999. UNIX IN A NUTSHELL, 3 RD Edition. Sebastopol, CA : O Reilly. CONTACT INFORMATION Your comments and questions are valued and encouraged. Contact the author at: James Willis OptumInsight 763-283-3654 james.willis@optum.com 7