Yalan enables you to build a database containing information extracted from the logs of your sas jobs.
The informations collected by Yalan include:

Data from Yalan imported into Excel
Getting Started
You do not have to change anything in your existing sas programs. The only thing you have to make sure is that your sas jobs write the logs to a file by setting the -ALTLOG option.
For example:
sas -sysin c:/saspgm/mypgm.sas
sas -sysin c:/saspgm/mypgm.sas -altlog c:/saslogs/mypgm.log
Yalan itself runs as a separate sas job that executes the macro "rdsStartYalan". "rdsStartYalan" contains all the configuration you have to provide:
%macro rdsStartYalan;
%* Reset configuration;
%rdsYalan (resetLogFiles);
%* Where to look for new log files;
%rdsYalan (addLogFiles, c:\saslogs, *.log);
%rdsYalan (addLogFiles, c:\saslogs, *.saslog);
%* In which time intervall to look for new log files;
%rdsYalan (setPollingInterval, 15);
%* Set the library (e.g. "c:/MyLDB") to write the log database to and (optionally)
name the share server to access the log database (e.g. "sassrvt1");
%rdsYalan (setLDBLibrary, c:\sasldb, sassrvt1);
%* Yalan will execute the statements contained in the following file every time
it polls for new log files. You may stop the Yalan Daemon by passing the
following statement via this file: %rdsYalan (stopDaemon);
%rdsYalan (setCommandFile, c:\sasldb\yalanCmds.sas);
%* Start the Yalan daemon;
%rdsYalan (startDaemon);
%mend;
options nomprint nomlogic nosource notes;
%rdsStartYalan;
As soon as a log file is written by one of your sas jobs to a file named in the "addLogFiles" call it will be read into the log database.
Reading single Log Files
If you want to use Yalan to read single log files into the log database, use the macro "rdsLogReaderSAS".
libname lib1 'c:\MyLDB';
%rdsLogReaderSAS
( readLog
, logFileName=c:\saslogs\saslog24665.log
, logData=rdsLog
, stepData=rdsStep
, ioData=rdsIO
, errorData=rdsError
, dbLibName=lib1
);
Yalan on the MVS Platform
Yalan has been tested to run on MVS.
Here is an example of how "rdsStartYalan" might look like on MVS:
%macro rdsStartYalan;
%* Reset configuration;
%rdsYalan (resetLogFiles);
%* Where to look for new log files;
%rdsYalan (addLogFiles, JOB.DWHHU, *);
%* In which time intervall to look for new log files;
%rdsYalan (setPollingInterval, 15);
%* Set the library (e.g. "c:/MyLDB") to write the log database to and (optionally)
name the share server to access the log database (e.g. "sassrvt1");
%rdsYalan (setLDBLibrary, dwh.sas.ldb);
%* Yalan will execute the statements contained in the following file every time
it polls for new log files. You may stop the Yalan Daemon by passing the
following statement via this file: %rdsYalan (stopDaemon);
%rdsYalan (setCommandFile, dwh.yalan.pgm(cmdYalan));
%* Start the Yalan daemon;
%rdsYalan (startDaemon);
%mend;
options nomprint nomlogic nosource notes;
%rdsStartYalan;
There are two aspects concerning code formatting and naming conventions you have to be aware of when installing Yalan on MVS:
The best way to deploy Yalan on MVS is to allocate a PO library with LRECL 256, and proceed as follows:
When running the Yalan daemon on MVS you need to make sure that the filename SYSIN is available for IDCAMS which is called by Yalan. You therefore have to pass the code to be executed by SAS in another filename than SYSIN. Use a JCL like the following:
//DWHYALAN JOB (DWH,KKS,S777),MSGCLASS=X,MSGLEVEL=(1,1),CLASS=D,
// TIME=(100,0),NOTIFY=&SYSUID
/*JOBPARM S=ANY
//YALAN EXEC SAS,OPTIONS='SYSIN=SASINPUT'
//SASINPUT DD *
OPTIONS S=256 ERRORABEND;
// DD DISP=SHR,DSN=DWH.YALAN.PGM(ALLYALAN)
// DD DISP=SHR,DSN=DWH.YALAN.PGM(RDSYALAN)
// DD *
%rdsStartYalan;
/*
Contact
For comments or questions on Yalan please contact:
Kybeidos GmbH
Stephan Frenzel
Moltkestrasse 27
69120 Heidelberg
Germany
stephan.frenzel@kybeidos.de

-----Directory-----
File
# Name Memtype Size Last Modified
----------------------------------------------
1 ERROR DATA 17408 20FEB2005:18:02:16
2 IO DATA 82944 20FEB2005:18:02:16
3 LOG DATA 17408 20FEB2005:18:02:16
4 STEP DATA 9216 20FEB2005:18:02:16
Data Set Name: LDB.LOG Observations: 2
Member Type: DATA Variables: 7
-----Alphabetic List of Variables and Attributes-----
# Variable Type Len Pos Format Label
-----------------------------------------------------------------------------
1 logId Num 8 0 8. Sequence Number of Log
2 logFileName Char 256 32 $256. Name of Log File
3 logDigest Num 8 8 12. Digest of Log
4 project Char 20 288 $20. Name of Project
5 job Char 20 308 $20. Name of Job
6 date Num 8 16 YYMMDD10. Date
7 time Num 8 24 TIME10. Time
Data Set Name: LDB.ERROR Observations: 1
Member Type: DATA Variables: 5
-----Alphabetic List of Variables and Attributes-----
# Variable Type Len Pos Format Label
----------------------------------------------------------------------------
1 logId Num 8 0 8. Sequence Number of Log
2 step Num 8 8 5. Number of step
3 errorMessage Char 256 32 $256. Error Message
4 errorSeverity Num 8 16 3. Severity of Error
5 lineNo Num 8 24
Data Set Name: LDB.IO Observations: 93
Member Type: DATA Variables: 11
-----Alphabetic List of Variables and Attributes-----
# Variable Type Len Pos Format Label
--------------------------------------------------------------------------------------------
1 logId Num 8 0 8. Sequence Number of Log
2 step Num 8 8 5. Number of step
3 no Num 8 16 3. Number of data source within step
4 inputType Char 3 40 $3. Type of input data source
5 inputName Char 80 43 $80. Logical name of input data source
6 inputLibFileName Char 256 123 $256. Physical name of input file or library
7 inputObs Num 8 24 12. Number of observation read from input data source
8 outputType Char 3 379 $3. Type of output data source
9 outputName Char 80 382 $80. Logical name of output data source
10 outputLibFileName Char 256 462 $256. Physical name of output file or library
11 outputObs Num 8 32 12. Number of observation written to output data source
Data Set Name: LDB.STEP Observations: 89
Member Type: DATA Variables: 7
-----Alphabetic List of Variables and Attributes-----
# Variable Type Len Pos Format Label
--------------------------------------------------------------------------------------
1 logId Num 8 0 8. Sequence Number of Log
2 step Num 8 8 5. Number of step
4 stepCPUTime Num 8 16 COMMAX12.2 CPU time of step
3 stepName Char 8 48 $8. Data step or procedure name
5 stepRealTime Num 8 24 COMMAX12.2 Elapsed time of step
6 stepTaskMemory Num 8 32 12. Memory usage of step
7 lineNo Num 8 40
The Zip-Archive you can download with the link below contains the complete source code as well as some documentation (MS-Word, PDF, HTML) explaining how to use Yalan.
Download the Yalan-Archive here!
Please note that Yalan is available under the terms of the GPL.
Below you will find some of the question (and answers :-) which arise when installing and using Yalan in various enviromnents.
If you get a message like this in an MVS environment:
NOTE: The initialization phase used 0.05 CPU seconds and 5436K. ERROR: Macro keyword PUT appears as text. A semicolon or other delimiter may be missing. ERROR: Macro keyword PUT appears as text. A semicolon or other delimiter may be missing. ERROR: Macro keyword PUT appears as text. A semicolon or other delimiter may be missing. 6954 %RDSSTARTYALAN;
... the reason is most propably, that SAS does not expect source lines to be longer than 72 or 80 characters.
To resolve this, set the option "S=256" before including the Yalan sources.
In der folgenden Mail beschreibt "Rich" seine Erfahrung mit Yalan unter Unix. Er hat noch einigen Anpassungsbedarf identifiziert (wir werden seine Anregungen in die nächste Version einfließen lassen), was ihn aber nicht daran hindert, sich lobend zu äußern - Danke!
Many thanks for letting me use YALAN, it's proving very useful. Looking at the website and docs it seems your primarily developing it for Windows and MVS. What I need it for is Windows and Unix. For Windows, as I say, it's fine, it works well. For Unix, you'll be pleased to know, it is essentially fine too, it just require one or two small changes which you may wish to employ...
1.
The first is that SAS Unix just cannot deal with mixed case macro variables. An unbelievably absurd point but true. So macros such as 'rdsFileFinder' are just not seen by SAS. However, I've changed all the macros (see attachment) so they can be read by Unix. the rename is simple; basically macro 'rdsFileFinder' becomes 'macro rds_file_finder'. Not too tricky and obviously works fine in Windows (no idea about MVS).
(..as an aside, I noticed macro 'rdsFileFinder' was not referenced by any of your other macros though 'rds_fileFinder' was. I'm assuming a typo or old macro name. I changed the macro referencing 'rds_FileFinder' to the new 'rds_File_Finder' name. I hope that's OK..)
2.
At some point you must read in the log file (bear in mind I only use the 'rds_log_reader_sas' macro) and input using delimiters. Unix annoyingly leaves on its line endings so all of the values of the character variables from your output datasets have this line ending. Knowing that the hex value for unix line endings is "'0d'x", you could stick this in your "dlm" parameter alongside the others (e.g. "dlm='0a0d'x" would delimit on tabs *and* Unix line endings) or explicitly filter them out with the following sort of code:-
data IO(drop=i);
set IO;
array temp[*] _character_;
do i=1 to dim(temp);
temp[i]=translate(temp[i],'','0d'x);
end;
run;
This is what I do for now.
3.
You may or may not know this but the SAS god have decided that for SAS 9, Proc SQL cannot write to a table it is reading from without printing a warning to the log (e.g. "create table x as select * from x" is no longer advised). This is not the end of the world, of course, as it still works but as I say, a warning is printed for each log read (incidentally, I *think* it is the section of code that starts "create table log1 as select logDigest..." where the problem is caused).
Anyway, I hope this helps you and well done for producing such an excellent tool.
Many thanks, Rich
If you receive the error message:
MPRINT(RDSLOGFILEPOLLER): proc sort data=lib1.logFile; MPRINT(RDSLOGFILEPOLLER): by pathName; ERROR: Variable PATHNAME not found. ERROR: Variable PATHNAME not found. ERROR: Variable PATHNAME not found.
... the reason might be that there has been an error in the run, that initialized the log database.
To solve this problem delete all data sets from the log database and restart Yalan.