Problem Solvers

12月 222022
 

How often have you wanted a secret decoder ring to view the resolved values of your macro variables or to isolate an error or warning that is occurring in your SAS macro code logic? Well, the MFILE option can be that decoder!

When you use the MFILE and MPRINT options and use a FILENAME statement with the MPRINT fileref, SAS routes the code that is generated and submitted by your macro to a text file the next time that you call your macro. You can then examine and run all or part of the code in the text file to help debug your program. This blog post provides three examples of how you can use these options to improve your use of macro code.

Example 1: Understanding the macro code

Here’s an example where I am using code that was written by another programmer. I want to understand what the macro variables inside the TEST macro resolve to and what SAS code the TEST macro creates:

 %macro test(value);
 
   ods rtf file="&value..rtf";
     proc print data=one(where=(state="&value"));
     run;
   ods rtf close;
 
   %mend;
 
data one;
     input state $ age;
   datalines;
   VA 21
   VA 23
   MD 23
   MD 12
   MA 12
   MA 34
   ;
 
   proc sort ;
     by state;
   run;
 
  data _null_;
     set one;
     by state;
     if first.state then
       call execute('%test('||state||')');
   run;

Here is how I call the TEST macro with the MFILE and MPRINT options in effect and a FILENAME statement that uses the MPRINT fileref:

   options mprint mfile;
   filename mprint "c:\temp\nomacro.sas";
 
  data _null_;
     set one;
     by state;
     if first.state then
       call execute('%test('||state||')');
   run;

This program results in the following code being sent to the nomacro.sas file:

ods rtf file="MA.rtf";
proc print data=one(where=(state="MA"));
run;
ods rtf close;
ods rtf file="MD.rtf";
proc print data=one(where=(state="MD"));
run;
ods rtf close;
ods rtf file="VA.rtf";
proc print data=one(where=(state="VA"));
run;
ods rtf close;

In the file, I see that all of the macro variables resolved to state abbreviations, and I can then choose to run all or part of the code as desired. That was easy!

Example 2: Understanding exactly where an issue occurs in macro code

In the following log file, I’m confused because the NOTE about an invalid argument to the INPUT function seems to occur on the line where I invoked my macro and I want more specific information:

Kevin Russell explains why the NOTE occurs in this location in his Surviving the SAS® Macro Jungle by Using Your Own Programming Toolkit paper:

The line number in the NOTE points to the line where the macro is invoked instead of pointing to the line that contains the INPUT function. The NOTE points to this line because it is the invocation of the macro that generates the INPUT function code that then generates the NOTE. Because there is currently no option other than having the NOTE point to the line where the macro is invoked, you can use the MFILE system option to debug.

I can use the MFILE option to discover where the problem with the INPUT function actually occurs:

filename mprint "c:\temp\nomacro_note.sas";
options mprint mfile;
%cars

The resulting submission of the code from the nomacro_note.sas file helps me find the problematic line, line 75. It is not hard to find the issue when you use the problematic function only one time; but in the real world, these functions are used OFTEN:

Example 3: Including dependent code for the macro

What if I have some precode that is outside of the macro, or another macro that I need to use as part of my debugging? In this case, I am not sure that I will need a PROC PRINT step to debug my CARS macro, but I would like to ensure that it is included in my decoded file (using MFILE). So, I can use the MFILE option to include that code in a file that I can parse out later. Here's the code that I want to run:

%let name1=Asia;
%let i=1;
 
proc print data=sashelp.cars; 
 title "&&name&i";
run;
 
%macro cars;
data cars;
 set sashelp.cars;
 new=input(origin,1.);
run;
%mend;

I wrap the code in the OUTER macro and then use MFILE and MPRINT to “decode”:

%macro outer;
%let name1=Asia;
%let i=1;
 
proc print data=sashelp.cars; 
 title "&&name&i";
run;
 
%macro cars;
data cars;
set sashelp.cars;
new=input(origin,1.);
run;
%mend;
 
%cars
 
%mend outer;
 
filename mprint "c:\temp\outer.sas";
options mprint mfile;
%outer

Here is the outer.sas file for later decoding:

proc print data=sashelp.cars;
title "Asia";
run;
data cars;
set sashelp.cars;
new=input(origin,1.);
run;

Conclusion

Paired with the MPRINT option, the MFILE option is especially helpful if you are seeing errors, warning messages, or code behavior that you cannot explain or diagnose easily from reading your SAS log. MFILE gives you clean code that you can submit, without having to copy the MPRINT output from the log window to another file and remove the (MPRINT) headers. It is a code strategy that might also prove useful if you need to involve SAS Technical Support, because it’s especially helpful for you to provide SAS Technical Support with the smallest subset of your code that demonstrates the problem that you are encountering.

Although these options are useful, note these restrictions:

  • If you generate code with MFILE, it does not contain any formatting such as code indention.
  • If you generate code with MFILE, it does not contain PL1 style comments (/* comment here */).
  • If the macro is a stored compiled macro that was compiled with the NOMPRINT option in effect, then the MFILE and MPRINT options do not generate a file.

Tell me how you have found this blog useful!

References:

SAS Help Center: MFILE Macro System Option

23138 - How can I remove macro code from my original program and create a file of the code that is generated by SAS so debugging the code is easier?

Surviving the SAS® Macro Jungle by Using Your Own Programming Toolkit

Decode your SAS® macro code with the MFILE and MPRINT options was published on SAS Users.

10月 212022
 

Introduction

The ODS Excel destination is popular because it generates presentational ready output directly from your SAS® software. This destination provides options to the Microsoft Excel worksheet and workbook that automate setting up custom features that you would otherwise manually add. This destination also includes other features such as the ability to add graphics generated by both SAS/GRAPH® and ODS Graphics, the ability to add formulas, and the ability to add SAS formats that are directly converted to the appropriate Excel formatting. This post demonstrates various formatting issues that can occur when using ODS Excel. It also describes the following:

  • handling those issues using formatting
  • formatting values after you export to Excel

Getting the desired formatting for your values

The ODS Excel destination and the Microsoft Excel application use the Excel General format for all numbers that do not have an Excel format applied. In ODS Excel, you can apply Excel formats using either a SAS format, which internally converts it to the comparable Excel format, or by applying the Excel format directly using the TAGATTR= style attribute. When you do not apply an Excel format, the Excel General format is used, which makes a best guess about how the output should be formatted. Here are some issues to consider when the Excel General format is used along with other Excel or ODS Excel defaults in ODS Excel:

  • Leading zeros are omitted when displaying values in the spreadsheet
  • Numbers greater than 11 digits might be displayed in scientific notation
  • Numbers greater than 15 digits are padded with zeros
  • Characters variables that contain commas or other punctuation get stripped

Retaining the leading zero

A number with a leading zero does not get preserved when it is exported to a worksheet using ODS Excel. This behavior occurs because the defaults in the Excel General format do not display numbers with a leading zero and is true whether the value is defined as character or numeric in SAS. The absence of the leading zero matters if this is an actual account number. Output 1 demonstrates the absence of the leading zero for both acct_num and acct_char in record 1.

Output 1. Exported output from ODS Excel does not include the leading zeros

To display the leading zero for variables that are defined as numbers in SAS using SAS formatting, apply the Z. SAS format, which is demonstrated in Example 1 below for the numeric variable acct_num. Character variables that are all numbers also use the Excel General format by default and require that you apply the character format $ to preserve the leading zero. You can also add Excel formats using the TAGATTR= attribute, which is used to apply the 0 format for the numeric field. This attribute uses the TYPE:STRING parameter in the TAGATTR= style attribute, which modifies the data type to a string that retains the leading zero in Excel. Output 2 shows the formatting that results from running the code in Example 1.

Example 1

data example_1;
input acct_num acct_char $;
cards;
0912556 0912556 
2330202 2330202 
;
run;
 
 
/* Using SAS formatting to preserve the leading zero. */
 
ods excel;
proc print data=example_1;
format acct_num z7.;
format acct_char $7.;
run;
ods excel close;
 
/* Using the TAGATTR= style attribute to preserve the leading zero. */
 
ods excel;
proc print data=example_1;
var acct_num /   style(data)={tagattr="format:0000000"};
var acct_char /  style(data)={tagattr="type:String"};
run;
ods excel close;

Output 2. The leading zero is retained

Preventing formatting with scientific notation

Exporting numbers using ODS Excel with values greater than 11 digits might display cells using scientific notation in the worksheet. This issue occurs regardless of how this number was defined in SAS unless an Excel format has been applied. Output 3 illustrates the issue.

Output 3. Outputs long numbers using scientific notation

To correct the formatting, add a SAS format such as the BEST. format for the numeric variable acct_num and the character format $ for the character variable acct_char. You can also apply a custom Excel format directly using a custom number format for the numeric variable and the TYPE:STRING parameter within the TAGATTR= attribute, which forces the type to be a string in Excel. Output 4 shows the formatting that results from running the code in Example 2.

Example 2.

data sample_2;
 input acct_num acct_char $12.;
 cards;
 123456789012 123456789012 
 456789012345 456789012345 
 ;
 run;
 
 
/* Using SAS formatting to display the full value. */
 
 ods excel file="c:\output\temp.xlsx";
 
 proc print data=sample_2;
 format acct_num best12.;
 format acct_char $12.;
 run;
 
 ods excel close;
 
/* Using the TAGATTR= style attribute to display the full value. */
 
 ods excel file="c:\output\temp.xlsx";
 
 proc print data=sample_2;
 var acct_num  / style(data)={tagattr="format:#####"};
 var acct_char / style(data)={tagattr="type:String"}; 
 run;
 
 ods excel close;

Output 4. Displays the full value

Excel pads values with zeros

Excel can store a number only up to 15 significant digits. After the 15th digit, Excel begins to pad the value with zeros, as shown in Output 5.

Output 5. Values are incompletely displayed

If you have a meaningful number that is greater than 15 digits, you must make sure that all digits are displayed. Since Excel cannot display more than 15 digits, this number must be treated as a string, which can be accomplished by using the TYPE:STRING parameter within the TAGATTR= attribute. However, you first must use the BEST. format to obtain all of the digits before storing this value as a string. Output 6 illustrates the formatting that you get after running the code from Example 3.

Example 3.

data sample_3;
 input acct_num acct_char $16.;
 cards;
 1234567890123456 1234567890123456 
 4567890123456789 4567890123456789 
 ;
 run;
 
 ods excel file="c:\output\temp.xlsx";
 
 proc print data=sample_3;
 var acct_num / style(data)={tagattr="type:String"};
 var acct_char; 
 format acct_num best16.;
 format acct_char $16.;
 
 run;
 
 ods excel close;

Output 6. The complete value is displayed

Character variables are stripped of punctuation

If a number contains punctuation such as a comma, it is stripped when it is exported to Excel using ODS Excel, as shown in Output 7.

Output 7. Output from the spreadsheet

If the expected behavior is to format the number with the punctuation in Excel, you can format it using both SAS formatting and Excel formatting. Example 4 uses the COMMA SAS format to format the value with commas. This example uses the character format $ to maintain the embedded punctuation within the character variable. Excel formatting is also applied to add the comma to both variables using the TAGATTR= style override. Output 8 shows the formatting that results from running the code in Example 4.

Example 4.

data example_4;
input acct_num comma5. +1 acct_char $5.;
cards;
3,000 4,000 
1,000 6,000 
;
run;
 
/* Using SAS Formatting to add or retain punctuation. */
 
ods excel;
 
proc print data=example_4;
format acct_num comma5.; 
format acct_char $5.;
var acct_num ;
var acct_char;
run;
 
ods excel close; 
/* Using the TAGATTR= style attribute to display the punctuation. */
ods excel;
proc print data=example_4;
var acct_num / style(data)={tagattr="format:#,###"};
var acct_char / style(data)={tagattr="format:#,###"};
run;
ods excel close;

Output 8. Punctuation is added or retained

Conclusion

This blog highlighted some of the potential formatting issues that you could encounter when exporting to Excel using the ODS Excel destination. ODS Excel does an amazing job at limiting some of these issues that exist with Excel in general. Hopefully the tips provided here will help you if you encounter any of these issues.

LEARN MORE | SAS® Output Delivery System (ODS)

Formatting your Microsoft Excel output using ODS Excel was published on SAS Users.

8月 172022
 

This post explains:

  • how the order of your data can differ when you run a DATA step with a BY statement in SAS®4 versus in CAS
  • how to achieve the same results in CAS by using the ADDROWID data set option, which was introduced in SAS® Viya®1

DATA step processing with a BY statement in SAS 9.4 and CAS

In SAS 9.4, the order of your data remains constant when you run a DATA step with or without a BY statement.

However, running a DATA step in CAS is different. It is essential to understand how processing works when running a DATA step in CAS to avoid possible unexpected results.

CAS DATA step processing overview

When a DATA step runs in CAS, CAS distributes the code and data across multiple workers and threads, as shown below:

Source:  SAS Help Center: Data Step Processing in CAS

The code that executes on each worker and thread is the same, but the portion of data is unique for that worker and thread.

CAS DATA step processing with a BY Statement

When you use a BY statement in the DATA step that is running in CAS, the data is grouped by the unique values of the BY variable. Each resulting BY group is maintained when distributing the code and data. However, because of the process by which CAS distributes and reassembles the data, the order of the data within each by group is not guaranteed. This change in order can occur with or without a BY statement. This reordering becomes very important when you use FIRST. and/or LAST. variables in your DATA step. Since the order is not guaranteed when running in CAS, results are almost assuredly different when you compare the output from running in SAS 9.4 to running in CAS.

Example of DATA Step in CAS

Here is an example of how the order of the data can be different when running a DATA step in CAS. In this example, I use the SASHELP.CARS data set. I compare the output of running a DATA step using BY-group processing in SAS 9.4 to the output produced from running the exact same code in CAS.

Here is the output from both PRINT procedures, which are clearly not the same. The model that is associated with the make is different in the output that is created in CAS.

The output from running the step in SAS 9.4 shows the make in alphabetic order with the first model based on an alphabetic sort order, which is the original order of the data. This output is the same each time I run this code in SAS 9.4. However, the value of model is not the same each time I run the step in CAS. When processing in CAS, the BY groups are retained, but the order of rows within the BY group cannot be guaranteed.

ADDROWID data set option

The ADDROWID data set option was created so that the results created in SAS can be replicated when running in CAS. This option creates the new variable _ROWID_ that increments numerically for each row in the table. The value of _ROWID_ is 1 for the first row, 2 for the second, 3 for the third, and so on. So you can perform BY-group processing using FIRST. and LAST. logic with ADDROWID to generate the same results in CAS that you get in SAS 9.4.

Example Using ADDROWID and _ROWID_ in CAS

Here is an example of how to use ADDROWID and _ROWID_ to maintain the order of the data. This is the same code I ran earlier in CAS, but this time, I used the ADDROWID option when creating the CARS table. Adding this option creates the sequential _ROWID_ variable that I can then use in the BY statement:

cas; /* Starts the CAS session. */
caslib _all_ assign; /* Creates the CASUSER libref. */
data casuser.cars(ADDROWID=YES);
  set sashelp.cars;
run;
/* Sorting the data is not required when you run in CAS. */
data casuser.cascars;
  set casuser.cars;
  by make _ROWID_;
  if first.make then output;
run;
proc print data=casuser.cascars(obs=10); 
var make model;
run;

Listing _ROWID_ as the last variable in the BY statement creates a unique BY group for each row. This code enables you to obtain the same results from running in SAS 9.4 when running the DATA step in CAS. Now, the output from the PROC PRINT steps shows that CAS matches the make and model from the values in the data set in the same way that they are matched in SAS 9.4:

Final thoughts

When running your DATA step in CAS, it is important to understand how the code and data is distributed and how this can affect your output. The order of your data can change when distributing the code and data across threads and workers and then reassembling the data after processing has finished. This is especially important to be aware of when you use BY-group processing in the DATA step.

Starting in SAS Viya 2020.1, the ADDROWID data set option was introduced to account for this behavior. This easy-to-use option allows you to ensure that the output produced when running your DATA step in CAS matches the output produced when running in SAS 9.4

References

SAS Institute Inc. 2022. "ADDROWID Data Set Option." In SAS® Viya® Programming Documentation. Cary, NC: SAS Institute Inc.

SAS Institute Inc. 2022. "Grouping and Ordering." In SAS® Viya® Programming Documentation. Cary, NC: SAS Institute Inc.

The ADDROWID data set option maintains the order of your data when executing a DATA step in SAS® Cloud Analytic Services (CAS) was published on SAS Users.

6月 102022
 

There are several alternatives to writing to a Microsoft Word file when you use the SAS® Output Delivery System (ODS). The RTF, TAGSETS.RTF and TAGSETS.RTF_SAMPLE destinations create an RTF formatted file. The WORD destination, which is still considered preproduction, creates a DOCX formatted file. The destinations provide many of the same functions, although some features are unique to each one. The destination that you choose might vary depending on your desired final output.

Both the Tagsets and the Word destination enable you to specify suboptions using the OPTIONS option. These suboptions are described in the documentation. For the Tagsets destinations, you can also see a list of the available suboptions and their values in the log by using the DOC='HELP' suboption as follows:

Ods tagsets.rtf file='test.rtf'
 options(doc='help');

What is common across destinations

There are some often-used features that are common across all ODS destinations that write to Microsoft Word. All ODS statements support the following options:

  • SASDATE – This option uses the date and time that the SAS session started if the DATE system option is turned on. Otherwise, the date and time listed are when the file is created. This is the default setting for the Tagsets destinations.
  • COLUMNS= – This option allows for multi-column output.
  • None of the destinations support the Report Writing Interface or the ODS LAYOUT ABSOLUTE option.
  • All destinations can create a table of contents, although the options for this task vary. To show the Table of Contents once the file is created, right-click in the page and select Update Field:
    • Ods rtf file='file.rtf' contents toc_data;
    • Ods tagsets.rtf file='file.rtf' options(contents='yes' toc_data='on');
    • Ods word file='file.docx' options(contents='yes' toc_data='on);
    • The TOC_LEVEL='n' suboption in the Tagsets and Word destinations controls the level of expansion of the table of contents.

Unique features, strengths and limitations for each destination

ODS RTF

The RTF destination was introduced in SAS® 8.1. The style template inherits from Styles.Printer. By default, title and footnote text is placed in the header and footer sections of the document. The BODYTITLE option in the ODS statement places the title and footnote text in the body of the document. The KEEPN option controls where tables are split on the page and the NOTRKEEP option controls whether table rows can be split by a page break.

A significant limitation of the RTF destination is that paging can be difficult because there is no vertical measurement. SAS allows Word to determine paging. In addition, the RTF destination does not support the UNIFORM option.

Here is an example:

ods _all_ close;
ods rtf file='paging_rtf.rtf' ;
 
proc print data=sashelp.cars(obs=15) noobs;
title 'Shows paging difficulties where columns wrap on the same page';
run;
 
ods _all_ close;

Shows paging difficulties where columns wrap on the same page

ODS Tagsets.RTF

The Tagsets.RTF destination was introduced in SAS® 9.2, partly to provide more control over paging. The style template inherits from Styles.Printer. Bodytitle is the default behavior, which means that the title and footnote text is placed in the body of the document. This destination supports the UNIFORM option. Another useful option is TABLEROWS=n, which specifies the number of rows in each table before ODS inserts a page break. Suboptions that are often used include the following:

  • CONTINUE_TAG= controls whether the “(Continued)” text is displayed at the end of a page when a table crosses a page boundary.
  • VSPACE= controls vertical space in the document.
  • WATERMARK= adds a diagonal text string as an argument.

Here is an example:

ods tagsets.rtf file='watermark_vspace_tagsets_rtf.rtf'
 options(doc='help' watermark="Draft" vspace='off') ;
 
proc print data=sashelp.class noobs;
title 'Shows watermark and no space between title and table';
run;
 
ods _all_ close;

Shows watermark and no space between title and table

ODS Tagsets.RTF_Sample

The Tagsets.RTF_Sample destination was also introduced in SAS 9.2. The style template inherits from Styles.Printer. The main distinction between this tagset and Tagsets.RTF is that this tagset places the title and footnote text in the header and footer of the Word document. This behavior makes it similar to the RTF destination without the BODYTITLE option. It includes the same suboptions listed in the ODS Tagsets.RTF section.

Here is an example:

ods tagsets.rtf_sample file='title_header_tagsets_rtf_sample.rtf'
 options(doc='help');
 
proc print data=sashelp.class noobs;
title 'Shows title in Header section of document';
run;
 
ods _all_ close;

Shows title in Header section of document

ODS WORD

The ODS WORD destination is still considered preproduction in the current release of SAS. It produces Microsoft Word output that is compatible with Microsoft Office 2010 and later. The style template inherits from Styles.Word and uses the SCHEME statement in the TEMPLATE procedure to define its style.

Some strengths of the ODS WORD destination are that it creates a native DOCX file and the file size can be smaller than that of a file created by the RTF destinations. The following file created with ODS WORD is 12 KB. The same file that is created with ODS RTF is 22 KB. There are several suboptions that help control where text splits on a page, including KEEP_LINES and KEEP_NEXT. The ODS WORD destination also supports accessibility and SVG output.

The ODS WORD destination currently does not support watermarks.

Here is an example:

ods word file='word_output.docx' sasdate;
 
proc print data=sashelp.class noobs;
title 'ODS WORD output';
run;
 
ods _all_ close;
ods listing;

ODS WORD output

Conclusion

Multiple ODS destinations can create a Microsoft Word file. Any method that you choose can create presentation-quality output for Microsoft Word. Thank you for reading and please check out the documentation links below.

Learn more

A comparison of the ODS destinations for writing to Microsoft Word was published on SAS Users.

4月 182022
 

SASPy and the SAS kernel for Jupyter Notebook enable you to connect to SAS® 9.4 and the SAS® Viya® compute server from your client machine. You can then interact with SAS and SAS Viya via Python. If you are not familiar with SASPy and the SAS kernel, this article provides an introduction.

Installing SASPy

SASPy is a client application. You install SASPy on the same client where Python is installed. If SAS is installed on a server, you do not need to install SASPy on the server (because it needs to be installed only on the client).

Since most users install Python, SASPy, and the SAS kernel on a Microsoft Windows client, this article assumes that your client is a Windows client too. But your client could also be a Linux or UNIX environment.

In most situations, installing SASPy on your client machine is as simple as issuing a Python PIP command on your client. For example, if your client is a Windows client, issue this command from a DOS prompt or DOS command line:

pip install saspy

To verify that SASPy is properly installed, submit the following client command:

pip show saspy

The information that is displayed by the pip show saspy command also tells you which version of SASPy is installed and the client directory in which SASPy is installed.

Installing the SAS kernel

The SAS kernel is also a client application. You install the SAS kernel on the same client where Python and SASPy are installed. Note that while the use of SASPy does not require the SAS kernel, the SAS kernel does require SASPy to be installed. Also, in order to use the SAS kernel, you must first be able to use SASPy to connect successfully to SAS or SAS Viya.

In most situations, installing the SAS kernel on your client machine is as simple as issuing a Python PIP command. For example, if your client is a Windows client, issue this command from a DOS prompt or DOS command line:

pip install sas_kernel

To verify that the SAS kernel is properly installed, submit the following client command:

pip show sas_kernel

The information that is displayed by the pip show sas_kernel command also tells you which version of the SAS kernel is installed and the client directory in which the SAS kernel is installed.

Python and Java dependencies

SASPy and the SAS kernel require Python 3.4 or higher.

Also, most configurations that use SAS 9.4 require that Java be installed on your client. To check to see whether you have Java on your client, issue the following command:

java -version

Common operating environments

This article discusses several commonly used operating environments that use SASPy and the SAS kernel:

  • A local SAS session that is running on Windows, where both SAS and SASPy are installed on the same local Windows client machine
  • A remote SAS session that is running on a Windows server
  • A remote SAS session that is running on a Linux server
  • A SAS Programming Runtime Environment (SPRE) compute server that is running as part of a SAS Viya installation

Connecting to a local SAS session that is running on Windows

A common scenario is to use SASPy with a local installation of SAS on Windows. In this case, use the WINLOCAL definition in your sascfg.py configuration file. The configuration file resides in your SASPy installation directory. To determine the exact name of that directory, issue the following command on your client machine:

pip show saspy

To use the WINLOCAL definition, find the following line in your sascfg.py file:

SAS_config_names=['default']

Modify the line to match the following:

SAS_config_names=['winlocal']

To connect to a local Windows installation of SAS, submit the following Python statements:

import saspy
import pandas as pd
sas = saspy.SASsession(cfgname="winlocal")

Connecting to a remote SAS session that is running on a Windows server

Another common scenario is to use SASPy on your client machine to connect to SAS 9.4, which is running on a separate Windows server. In this case, use the WINIOMWIN definition in your sascfg.py configuration file.

To use the WINIOMWIN definition, find the following line in your sascfg.py file:

SAS_config_names=['default']

Modify the line to match the following:

SAS_config_names=['winiomwin']

Then, farther down in your sascfg.py file, find the following default definition:

winiomwin  = {'java'    : 'java',
            'iomhost'   : 'windows.iom.host',
            'iomport'   : 8591,
            }

Modify the value for IOMHOST in this definition by specifying the host name of the SAS IOM server that is running on Windows.

Then, to connect to SAS 9.4 on your Windows server, submit the following Python statements from your client:

import saspy
import pandas as pd
sas = saspy.SASsession(cfgname="winiomwin")

Connecting to a remote SAS session that is running on a Linux server

You might use SASPy on your client machine to connect to SAS 9.4, which is running on a Linux server. In this case, use the WINIOMLINUX definition in your sascfg.py configuration file.

To use the WINIOMLINUX definition, find the following line in your sascfg.py file:

SAS_config_names=['default']

Modify the line to match the following:

SAS_config_names=['winiomlinux']

Then, farther down in your sascfg.py file, find the following default definition:

winiomlinux = {'java'   : 'java',
            'iomhost'   : 'linux.iom.host',
            'iomport'   : 8591,
            }

Modify the value for IOMHOST in this definition by specifying the host name of the SAS IOM server that is running on Linux.

Then, to connect to SAS 9.4 on your Linux server, submit the following Python statements from your client:

import saspy
import pandas as pd
sas = saspy.SASsession(cfgname="winiomlinux")

Connecting to a SPRE server that is running as part of SAS Viya

SASPy cannot connect directly to a SAS® Cloud Analytic Services (CAS) server that is running as part of SAS Viya. However, SASPy can connect to the SPRE server that is running as part of SAS Viya. (The SPRE server is also referred to as the compute server in SAS Viya.) In this case, use the HTTPVIYA definition in your sascfg.py configuration file.

To use the HTTPVIYA definition, find the following line in your sascfg.py file:

SAS_config_names=['default']

Modify the line to match the following:

SAS_config_names=['httpviya']

Then, farther down in your sascfg.py file, find the following default definition:

httpviya = {'ip'      : 'name.of.your.spre.server',
            'ssl'     : False,  # this will use port 80
            'context' : 'Data Mining compute context',
            'authkey' : 'viya_user-pw',
            'options' : ["fullstimer", "memsize=1G"]
            }

Modify the IP value in this definition by specifying the name of the SPRE server for your installation of SAS Viya.

Then, to connect to the SPRE server, submit the following Python statements from your client:

import saspy
import pandas as pd
sas = saspy.SASsession(cfgname="httpviya")

Using SASPy

After you connect successfully to SAS or the SPRE server, you can then submit Python statements via your client to interact with SAS. For example, you can display the first five rows (observations) in SASHELP.CLASS by submitting the following statements:

cars = sas.sasdata("cars","sashelp")
cars.head()

You can display summary statistics for SASHELP.CLASS with the following code:

cars = sas.sasdata("cars","sashelp")
cars.describe()

Using the SAS kernel for Jupyter Notebook

The SAS kernel enables you to use the Jupyter Notebook interface to execute SAS code and view results inline.

As previously noted, the SAS kernel requires SASPy to be installed. You also must be able to connect successfully to SAS or SAS Viya via SASPy. After you do so, after bringing up Jupyter Notebook, in the upper right-hand corner of your notebook, choose New > SAS.

After that, you can then submit regular SAS statements via Jupyter Notebook. Here is an example:

proc print data=sashelp.class;
run;

Additional resources and documentation

For additional information about using SASPy and the SAS kernel, see these resources:

Getting started using SASPy® and the SAS® kernel for Jupyter Notebook was published on SAS Users.

2月 152022
 

Where does SAS Studio store files, and how do you access them? The answer: it depends.

For an illustration, submit the following code in SAS Studio:

%put &sysscpl;

%put &syshostname;

%put &sysvlong;

The values that are returned in your log window show which operating system is being used to run SAS, the name of the server that is running Base SAS®, and the version of SAS that is running on that server.

If you are running the single-user edition of SAS® Studio, then SAS®9 is installed on your Microsoft Windows PC locally and you are running SAS Studio on your own personal machine. With this edition of SAS Studio, you can access files on your system and from any mapped drive that uses the Universal Naming Convention (UNC) standard.

However, if you are running an edition of SAS Studio other than the single-user edition, then the files that you create and the files that you have access to are stored on the server where SAS is running.

The server where SAS is running does not have access to the machine from which you are submitting code via the SAS Studio URL in a web browser. In SAS® Studio 3.x, which runs on SAS®9, the Server Files and Folders pane helps you visualize the locations that are accessible to your user ID on the server.

Use the following macro variable to determine where your Home directory is on the server that is running SAS:

%put &userdir;

Your user ID should have Read and Write access to that directory on the file system. Your SAS administration team should have shared best practices for where to store your files on the server and how you can access those files if needed on your local machine. In general, the quickest way to access a file is to right-click it and select Download File, as shown here:

Accessing files in SAS® Studio on SAS® Viya®

On SAS Viya, the file system might not be available to you. If that is the case, your files must be stored in the SAS Content folder. If you are not familiar with the  SAS Content folder in SAS Viya, it is important to understand that the folder does not exist via a physical path on the file system. When you store files in the SAS Content folder tree, you can use the FILESRVC file access method to access them with code. See the examples in 

This blog contains useful information about making files available to the SAS Content folder:

The following SAS Communities blog posts describe how your SAS administrator can make the file system available for you, depending on your version of SAS Viya:

If the file system has been made available for you, then this macro variable contains your default Home directory:

%put &_USERHOME ;

Your SAS server is displayed in the Explorer pane after the Folder Shortcuts entry. As shown below, a myfile.txt file is stored in the Home directory on the file system. Right-click it and select Download file to download it to your local machine:

In the above example, the SAS server is named “NFS mount” and the Home directory is named “Home.” However, the names will be specific to your environment.

Moving files from your local machine to SAS® Studio

To do the reverse and make files from your local machine available to the SAS server where SAS Studio is running, right-click the desired destination folder in the Explorer pane and select Upload files:

Figure 4

I hope that this information helps demystify where your files are stored when you use SAS Studio!

LEARN MORE | SAS TUTORIALS ON YOUTUBE

Where are the files that you have access to through SAS® Studio? was published on SAS Users.

12月 112021
 

SAS Studio is a very common interface to use to work with SAS® Cloud Analytic Services (CAS) data. The Libraries tree in SAS Studio displays SAS libraries (librefs) that contain your SAS data sets. To view CAS data in the Libraries tree, you need to associate a libref with the CAS library (or caslib) that contains your CAS tables.

This article discusses how you can define librefs to be associated with caslibs. The terms “libref” and “caslib” might be new to you, so here is a quick explanation of these terms.

  • A SAS library reference, or libref, is a shortcut name that points to a storage location on the server where your SAS files are stored.
  • A CAS library name, or caslib, is a shortcut name that references an in-memory space that holds your CAS tables.

The LIBNAME statement enables you to create these types of shortcut names.

What you see in the Libraries tree

The Libraries tree in SAS Studio displays the defined librefs where you can select and view your data sets. In the following image, the Libraries tree displays the default libraries:




Any user-defined libraries would appear in this list as well. Note: No caslibs are displayed in this list.

To view caslibs in the Libraries tree, you need to associate a libref with each caslib.

Use the CASLIB _ALL_ ASSIGN; statement to associate all caslibs

After you establish a CAS session (by using the CAS statement), you can associate a libref with each of the defined caslibs by running the following statement:

caslib _all_ assign;

After you submit this code, you can see in the log that a libref was created for each caslib, and the name of the caslib is used as the name of the libref.

After you define a libref for each caslib, the Libraries tree is then updated to include these new librefs, as shown in the following image. The librefs that are associated with caslibs are identified by a cloud and snowflake icon that is next to the caslib name:



You can also use the following SAS Studio snippet to create a libref for each caslib:
SAS Snippets ► SAS Viya Cloud Analytic Services ► Generate SAS librefs for caslibs

Use the LIBNAME statement and CAS engine to associate specific caslibs

The CASLIB _ALL_ ASSIGN; statement defines a libref for each of your caslibs. However, if you do not want to include all caslibs in the Libraries tree, you can define librefs for only the caslibs that you want to include.

To do that, use the LIBNAME statement with the CAS engine to define a libref that is associated with a specific caslib. The following statement shows the syntax to define the libref:

libname libref cas caslib=caslib;

Here, libref is the name that you choose for the SAS libref, and caslib is the name of the assigned caslib that you want to associate with the libref.

When you use the CASLIB _ALL_ ASSIGN; statement, the caslib name is used for the libref name. But the libref name does not have to be the same as the caslib name.

For example, the following statement creates a libref named MYCAS that is associated with the CASUSER caslib:

libname MYCAS cas caslib=CASUSER;

Ensure that the caslib is already defined before you associate it with a libref.

If you are not sure whether a caslib is defined, the following code generates a list of the available defined caslibs. The list is generated on the Results tab in SAS Studio:

proc cas;
table.caslibInfo;
quit;

Note that you can also use the CASLIB _ALL_ LIST; statement to view the list of caslibs in the SAS Studio log.

Whether you use the table.caslibInfo action or the CASLIB _ALL_ LIST; statement is a matter of preference for where you want to view the results.

Additional options are supported for the LIBNAME statement and can be found in the CAS LIBNAME engine documentation.

Troubleshooting

Some librefs are not shown

What if you followed the above instructions and see some, but not all, of the librefs for your caslibs in the Libraries tree?

The rules for caslib names are not the same as the rules for librefs, so not all caslib names can be used as libref names.

For example, when you use the CASLIB _ALL_ ASSIGN; statement, you might see a note like the following written to the log:

NOTE: CASLIB SystemData for session CASAUTO will not be mapped to SAS Library SystemData. The CASLIB name is not valid for use as a libref.

This note is produced because the LIBNAME statement attempted to define a libref named SystemData to be associated with the caslib SystemData. However, a libref name is limited to eight characters, so SystemData could not be used as a libref name.

The name that is used for a SAS libref must conform to the rules for a SAS name.

If a caslib name is longer than eight characters, you can use the LIBNAME statement with the CAS engine to associate your caslib with a libref that meets the requirements for a SAS name.

For example, to define a libref for the SystemData caslib, you can use a shorter libref name, such as SYSDATA:

libname sysdata cas caslib=SystemData;

In the following image, the Libraries tree now includes the SYSDATA libref, which enables you to view the CAS tables that are stored in the SystemData caslib.



Another issue that you might encounter is that the name of the caslib is defined as a SAS name literal, such as containing character spaces in the caslib name, and you cannot associate a libref with that caslib. The CAS LIBNAME engine does not support a SAS name literal for a caslib name.

When you want to specify a name for a caslib, keep these SAS name rules in mind.

CAS tables are not shown

What if you defined librefs for each of the caslibs that you want to view in the Libraries tree, but some CAS tables are not displayed for a caslib?

If the name of a CAS table does not comply with the VALIDMEMNAME rules, then the table is not displayed in SAS Studio. SAS Note 63538 provides more information about this issue.

Librefs are not assigned automatically

What if you want to be able to see your caslibs in the Libraries tree in SAS Studio every time that you sign in? For this preference, you can edit your autoexec file in SAS Studio and include the statements to automatically define the librefs for your caslibs.

Follow these steps:

  1. Select Options ► Autoexec file.
  2. In the file, enter each of the statements that you want to run every time that you sign in. Here are examples:
cas;
caslib _all_ assign;

You can also include the LIBNAME statements for your caslibs as well as any other SAS statements that you want to run each time you sign in to SAS Studio.

  1. Click Run to submit the statements.
  2. Open the Log tab to verify that your statements ran without error.
  3. Click Save.

With each subsequent sign-in for SAS Studio, the statements from your autoexec file are run automatically, and you then can view the librefs for your CAS tables in the Libraries tree.

Conclusion

CAS libraries enable you to access your CAS data. By defining the librefs for those caslibs in SAS Studio, you can have more interactive access to the CAS data.

Learn more

How to view CAS tables in SAS® Studio was published on SAS Users.

12月 112021
 

SAS Studio is a very common interface to use to work with SAS® Cloud Analytic Services (CAS) data. The Libraries tree in SAS Studio displays SAS libraries (librefs) that contain your SAS data sets. To view CAS data in the Libraries tree, you need to associate a libref with the CAS library (or caslib) that contains your CAS tables.

This article discusses how you can define librefs to be associated with caslibs. The terms “libref” and “caslib” might be new to you, so here is a quick explanation of these terms.

  • A SAS library reference, or libref, is a shortcut name that points to a storage location on the server where your SAS files are stored.
  • A CAS library name, or caslib, is a shortcut name that references an in-memory space that holds your CAS tables.

The LIBNAME statement enables you to create these types of shortcut names.

What you see in the Libraries tree

The Libraries tree in SAS Studio displays the defined librefs where you can select and view your data sets. In the following image, the Libraries tree displays the default libraries:




Any user-defined libraries would appear in this list as well. Note: No caslibs are displayed in this list.

To view caslibs in the Libraries tree, you need to associate a libref with each caslib.

Use the CASLIB _ALL_ ASSIGN; statement to associate all caslibs

After you establish a CAS session (by using the CAS statement), you can associate a libref with each of the defined caslibs by running the following statement:

caslib _all_ assign;

After you submit this code, you can see in the log that a libref was created for each caslib, and the name of the caslib is used as the name of the libref.

After you define a libref for each caslib, the Libraries tree is then updated to include these new librefs, as shown in the following image. The librefs that are associated with caslibs are identified by a cloud and snowflake icon that is next to the caslib name:



You can also use the following SAS Studio snippet to create a libref for each caslib:
SAS Snippets ► SAS Viya Cloud Analytic Services ► Generate SAS librefs for caslibs

Use the LIBNAME statement and CAS engine to associate specific caslibs

The CASLIB _ALL_ ASSIGN; statement defines a libref for each of your caslibs. However, if you do not want to include all caslibs in the Libraries tree, you can define librefs for only the caslibs that you want to include.

To do that, use the LIBNAME statement with the CAS engine to define a libref that is associated with a specific caslib. The following statement shows the syntax to define the libref:

libname libref cas caslib=caslib;

Here, libref is the name that you choose for the SAS libref, and caslib is the name of the assigned caslib that you want to associate with the libref.

When you use the CASLIB _ALL_ ASSIGN; statement, the caslib name is used for the libref name. But the libref name does not have to be the same as the caslib name.

For example, the following statement creates a libref named MYCAS that is associated with the CASUSER caslib:

libname MYCAS cas caslib=CASUSER;

Ensure that the caslib is already defined before you associate it with a libref.

If you are not sure whether a caslib is defined, the following code generates a list of the available defined caslibs. The list is generated on the Results tab in SAS Studio:

proc cas;
table.caslibInfo;
quit;

Note that you can also use the CASLIB _ALL_ LIST; statement to view the list of caslibs in the SAS Studio log.

Whether you use the table.caslibInfo action or the CASLIB _ALL_ LIST; statement is a matter of preference for where you want to view the results.

Additional options are supported for the LIBNAME statement and can be found in the CAS LIBNAME engine documentation.

Troubleshooting

Some librefs are not shown

What if you followed the above instructions and see some, but not all, of the librefs for your caslibs in the Libraries tree?

The rules for caslib names are not the same as the rules for librefs, so not all caslib names can be used as libref names.

For example, when you use the CASLIB _ALL_ ASSIGN; statement, you might see a note like the following written to the log:

NOTE: CASLIB SystemData for session CASAUTO will not be mapped to SAS Library SystemData. The CASLIB name is not valid for use as a libref.

This note is produced because the LIBNAME statement attempted to define a libref named SystemData to be associated with the caslib SystemData. However, a libref name is limited to eight characters, so SystemData could not be used as a libref name.

The name that is used for a SAS libref must conform to the rules for a SAS name.

If a caslib name is longer than eight characters, you can use the LIBNAME statement with the CAS engine to associate your caslib with a libref that meets the requirements for a SAS name.

For example, to define a libref for the SystemData caslib, you can use a shorter libref name, such as SYSDATA:

libname sysdata cas caslib=SystemData;

In the following image, the Libraries tree now includes the SYSDATA libref, which enables you to view the CAS tables that are stored in the SystemData caslib.



Another issue that you might encounter is that the name of the caslib is defined as a SAS name literal, such as containing character spaces in the caslib name, and you cannot associate a libref with that caslib. The CAS LIBNAME engine does not support a SAS name literal for a caslib name.

When you want to specify a name for a caslib, keep these SAS name rules in mind.

CAS tables are not shown

What if you defined librefs for each of the caslibs that you want to view in the Libraries tree, but some CAS tables are not displayed for a caslib?

If the name of a CAS table does not comply with the VALIDMEMNAME rules, then the table is not displayed in SAS Studio. SAS Note 63538 provides more information about this issue.

Librefs are not assigned automatically

What if you want to be able to see your caslibs in the Libraries tree in SAS Studio every time that you sign in? For this preference, you can edit your autoexec file in SAS Studio and include the statements to automatically define the librefs for your caslibs.

Follow these steps:

  1. Select Options ► Autoexec file.
  2. In the file, enter each of the statements that you want to run every time that you sign in. Here are examples:
cas;
caslib _all_ assign;

You can also include the LIBNAME statements for your caslibs as well as any other SAS statements that you want to run each time you sign in to SAS Studio.

  1. Click Run to submit the statements.
  2. Open the Log tab to verify that your statements ran without error.
  3. Click Save.

With each subsequent sign-in for SAS Studio, the statements from your autoexec file are run automatically, and you then can view the librefs for your CAS tables in the Libraries tree.

Conclusion

CAS libraries enable you to access your CAS data. By defining the librefs for those caslibs in SAS Studio, you can have more interactive access to the CAS data.

Learn more

How to view CAS tables in SAS® Studio was published on SAS Users.

10月 202021
 
As defined in the SAS® 9.4 Stored Processes: Developer's Guide, Third Edition, a stored process "is a SAS program that is stored on a server and defined in metadata, and which can be executed as requested by client applications." One of the benefits of using stored processes is that client applications always have the latest version of the code. In addition, stored processes provide enhanced security and application integrity.

Have you ever submitted a stored process, and instead of the expected output, you saw errors or no output at all? Depending on how you submit the stored process, various logs are available to assist you with debugging.

This article provides guidance for understanding which situations call for which logs, where to find each log, and what you should look for in each log. The article uses two clients as examples: SAS® Enterprise Guide® and the SAS® 9.4 Stored Process Web Application.

The article is divided into two sections:

  • Frequently Used Logs
  • Infrequently Used Logs

Frequently Used Logs

The logs that are described in this section are the most prevalent logs that you request when a stored process does not execute properly or when there seems to be a problem with the stored-process server.

SAS® Object Spawner log

What

The SAS Object Spawner log records anytime that the spawner tries to start or stop a stored-process server, a workspace server, or a pooled workspace server. It also records when a request is redirected to a running stored-process server or a pooled workspace server or to a SAS® Grid Manager server.

The syntax for this log's name is ObjectSpawner_yyyy-mm-dd_machine-name_process-ID.log.

Where

The default locations for the object-spawner log are as follows:

  • Microsoft Windows operating environments: SAS-configuration-directory\Lev1\ObjectSpawner\Logs
  • UNIX operating environments: SAS-configuration-directory/Lev1/ObjectSpawner/Logs

If the logs are not in the directories that are listed above, you can check the logconfig.xml file that resides in the SAS-configuration-directory\Lev1\ObjectSpawner\ directory. That file contains a parameter called FileNamePattern that determines the location of the object-spawner log, as shown in this example:

<param name="FileNamePattern" value="/sas/config/Lev1/ObjectSpawner/Logs/ObjectSpawner_%d_%S{hostname}_%S{pid}.log"/>

Why

Here are some reasons why you should check the object-spawner log:

  1. Performance problems occur within stored processes.
  2. Servers do not start or servers stop working. The stored process server, the workspace server, and the pooled workspace server are all started by the object spawner.
  3. Running a stored process returns no results and no errors.
  4. Users do not have permission to start the server or do not have ReadMetadata permission on their application server context (for example, the SASApp application server).
  5. The connecting user has to wait longer than the availability time-out of 60 seconds, and the stored process fails.
  6. A server is not available on which to run a stored process.

The following error is an example of one that you might find in this log:

The launch of the server process failed due to a problem with the processing of the SAS logging facility configuration file (LOGCONFIGLOC).

This error might occur because the file that is specified for the -LOGCONFIGLOC option cannot be processed. The option either is invalid or it cannot be accessed.

For more examples of errors that you might see in the object-spawner log, see the section Object Spawner Messages in "Appendix 1: Object Spawner and SAS OLAP Server Messages" in the SAS® 9.4 Intelligence Platform: Application Server Administration Guide.

You can also enable more detailed logging within the object-spawner log by following the steps in Enable More Detailed Logging for SAS Object Spawner Troubleshooting in "Chapter 10, Administering Logging for SAS Servers" of the SAS® 9.4 Intelligence Platform: System Administration Guide, Fourth Edition.

Example and possible cause

Let’s look at an example of how the object-spawner log can be helpful.

Suppose that the stored-process server fails to validate. Within the object-spawner log, you might see an error like the following:

Error authenticating user domain\sassrv in function LogonUser. Error 1326 (The user name or password is incorrect. ).
 
The credentials specified for the SASApp – Stored Process Server (A5WN99NR.AZ000007) server definition failed to authenticate. Therefore this server definition will not be included.

With this type of error, you might have an invalid sassrv password. You can check the password by trying to log on to the server directly with the sassrv user ID. If the logon is successful, open SAS® Management Console and verify that the password is correct in the metadata, as follows:

  1. In SAS® Management Console, select User Manager.
  2. Locate the SAS General Servers group. Then, right-click and select Properties.
  3. Click the Accounts tab.
  4. Select the sassrv user ID. Then click Edit.
  5. Update the password to what was successful on the operating system.
  6. Restart the object spawner.
  7. Check the logs again to verify that the error is resolved.

Object-spawner console log

What

The object-spawner console log, available only on UNIX platforms, does not actually contain information about the object spawner. Instead, this log contains STDERR and STDOUT messages about the applications that are launched by the object spawner. The syntax for this log's name ObjectSpawner_console_machine-name.log.

Where

Under UNIX, the default location for the object-spawner console log is SAS-configuration-directory/Lev1/ObjectSpawner/Logs.

Why

Here are some reasons why you should check this log:

  • SAS modules are missing. The program tries to run SAS modules that are not present in your environment.
  • Possible memory issues occur.
  • Storage or space issues occur.
  • Possible encoding issues occur.
  • Library permission issues occur.

The following error is an example of one that you might find in the object-spawner console log:

ERROR: Could not find extension: (sasgis)

This error can occur when someone or some component runs code that either checks for the existence of certain SAS modules or that contains references to certain SAS modules that are not present in your environment. Because these modules do not exist, errors are written to the log. This behavior is expected, and it is not indicative of any larger issue. So, you can ignore these messages.

Example and possible cause

Let’s look at an example of how the object-spawner console log can be helpful.

Suppose that your program generates a segmentation violation, but there is no indication as to why that happens. Within the object-spawner console log, you might see an error like the following:

ERROR: No space left on device

This type of error is an indication that you might be running out of disk space. Try adding more space, point to a network drive, or use smaller files.

SAS® Stored Process Server log

You need to enable verbose logging to see every stored process that runs through the server. For more details about verbose logging, see SAS Note 34114, "Creating a detailed SAS® Stored Process Server log by default."

What

The syntax for the SAS Stored Process Server log name is SASApp_STPServer_yyyy-mm-dd_machine-name_process-ID.log.

Where

The default locations for the stored-process server log are as follows:

  • Windows: SAS-configuration-directory\Lev1\SASApp\StoredProcessServer\Logs
  • UNIX: SAS-configuration-directory/Lev1/SASApp/StoredProcessServer/Logs

Why

Here are the reasons that you might need to check this log:

  • Performance problems occur.
  • You do not receive any results. That is, the stored process runs, but it does not return an error, a warning, or the expected results.

Here is an example of an error that you might see in the log:

ERROR: A lock is not available for library.dataset.data
ERROR: Lock held by process 26834

This error indicates that the data set that is shown in the error cannot be locked for processing because the lock is held by another process. Further investigation of the stored-process server log that contains process ID 26834 shows the DATA step that is also reading from the same data set, which causes the lock.

Here is another error that you might see in this log:

ERROR: No logical assign for filename _WEBOUT.

Possible causes

The two main reasons for this error are as follows:

  • The %STPBEGIN and %STPEND macros are enabled.
  • The item Package is selected under the Result capabilities section (via Execution Options ► Result capabilities in either SAS Management Console or SAS Enterprise Guide)

The object-spawner console log is often needed in conjunction with the object-spawner log so that you can evaluate the communication between them.

SAS® Stored Process web-application log

What

The SAS Stored Process web-application log resides on the middle-tier machine, and the syntax for the log's name is SASStoredProcess9.4.log. (Note: The 9.4 in SASStoredProcess9.4.log will change with new releases.)

Where

The default locations for this log are as follows:

  • Windows: SAS-configuration-directory\Lev1\Web\Logs\SASServer1_1
  • UNIX: SAS-configuration-directory/Lev1/Web/Logs/SASServer1_1

Why

Here are some scenarios for which you might want to check this log:

  • HTTP errors are displayed in the browser when you submit the stored process from the SAS Stored Process Web Application.
  • Pages in the stored-process web application (for example, the welcome page, index page, or custom input form) do not load or they take a long time to load.
  • A dynamic prompt cannot load.

Examples

The following error occurs when dynamic prompts from a data set and the SAS General Servers user group are denied ReadMetadata permission in SAS Management Console for that specific stored process:

2021-07-30 15:01:43,494 [tomcat-http--10] WARN [sasdemo] com.sas.prompts.valueprovider.dynamic.workspace.PromptColumnValueProvider - Cannot resolve data type
2021-07-30 15:01:43,505 [tomcat-http--10] ERROR [sasdemo] com.sas.prompts.valueprovider.dynamic.workspace.PromptColumnValueProvider - Unable to find physical table
com.sas.storage.exception.ServerConnectionException: Unable to find physical table
	at com.sas.prompts.valueprovider.dynamic.DataProviderUtil.getLibrary(DataProviderUtil.java:163)
	at com.sas.prompts.valueprovider.dynamic.workspace.PromptColumnValueProvider.setConnection(PromptColumnValueProvider.java:815)
	at com.sas.prompts.valueprovider.dynamic.workspace.PromptColumnValueProvider.getValuesAsList(PromptColumnValueProvider.java:647)
	at com.sas.prompts.valueprovider.dynamic.workspace.PromptColumnValueProvider.getValues(PromptColumnValueProvider.java:633)

The following pop-up message occurs because the SAS General Servers user group or the sasdemo user ID are denied permission to the data set that is needed for the prompts for a stored process.

Unable to execute query: SQL passthru expression contained these errors: ERROR: File MYLIB.MYCLASS.DATA does not exist

When you run a stored process from the SAS Stored Process Web Application, it is often helpful to add debugging options to the end of the URL by using the reserved macro variable _DEBUG. The following example URL demonstrates how to use the TRACE and LOG options to obtain pertinent information in the log that is produced in the browser.

http://your.web.server:8080/SASStoredProcess/do?_program=/STP_Examples/test1&_debug=trace,log

For a complete list of _DEBUG= values, see List of Valid Debugging Keywords in "Chapter 7: Building a Web Application with SAS® Stored Processes" in the SAS® 9.4 Stored Processes: Developer's Guide, Third Edition.

Workspace-server log

What

You must request logging for the workspace-server log because it is not one that is enabled, by default. The syntax for the log's name is SASApp_WorkspaceServer_yyyy-mm-dd_machine-name_process-ID.log.

Where

As mentioned earlier, you must request logging for this log, as follows:

  • Windows: In the sasv9_usermods.cfg file that resides in SAS-configuration-directory\Lev1\SASApp\WorkspaceServer\ directory, add the following command to turn on logging:
    -logconfigloc SAS-configuration-directory\Lev1\SASApp\WorkspaceServer\logconfig.trace.xml"

    This setting generates the log file in SAS-configuration-directory\Lev1\SASApp\WorkspaceServer\Logs.

  • UNIX: In the sasv9_usermods.cfg file that resides in SAS-configuration-directory/Lev1/SASApp/WorkspaceServer/logconfig.trace.xml"
    to /Lev1/SASApp/WorkspaceServer/
    directory, add the following command to turn on logging:

    -LOGCONFIGLOC SAS-configuration-directory/Lev1/SASApp/WorkspaceServer/logconfig.trace.xml"

    This setting generates the log file that resides in SAS-configuration-directory/Lev1/SASApp/WorkspaceServer/Logs.

Why

If you run the stored process from the SAS Stored Process Web Application with the server set to the workspace server, you need to consult this log for any errors or warnings. Running the stored process from SAS Enterprise Guide produces a log directly in the application. You need to consult the workspace server log in either of these circumstances:

  • when Default server is selected as the server type in the stored-process properties
  • when you submit the stored process from SAS Enterprise Guide

Pooled workspace-server Log

What

The syntax for the pooled workspace-server log's name is SASApp_PooledWSServer_yyyy-mm-dd_machine-name_process-ID.log.

Where

The default locations for this log are as follows:

  • Windows: SAS-configuration-directory\ Lev1\SASApp\PooledWorkspaceServer\Logs
  • UNIX: SAS-configuration-directory/Lev1/SASApp/PooledWorkspaceServer/Logs

Why

The pooled workspace server loads dynamic prompt values in the SAS Stored Process web application. So, you need this log if a dynamic prompt does not load.

SAS® Metadata Server Log

What

The syntax for the SAS Metadata Server log' name is SASMeta_MetadataServer_yyyy-mm-dd_machine-name_process-ID.log

Where

The default locations for the metadata-server log are as follows:

  • Windows: SAS-configuration-directory\Lev1\SASMeta\MetadataServer\Logs
  • UNIX: SAS-configuration-directory/Lev1/SASMeta/MetadataServer/Logs

Why

This log is helpful for issues with the LIBNAME META engine and metadata permissions.

The following error is written to the metadata-server log when no metadata identity is associated with the user name and password.

ERROR [00000779] 28:billyw - User Folders cannot be created or retrieved if connected user ID is not a person identity. Must be connected as a person identity or valid person name must be passed in request.

The following messages might also be written to this log when you try to open SAS Management Console and when the user billyw requires log on as a batch job user rights at the operating system level.

20100122:13.00.36.82: 00002410:NOTE:    User tbanks probably does not have the right to log on as a batch job.
20100122:13.00.36.82: 00002410:ERROR:   Error authenticating user tbanks in function LogonUser.  Error 1385 (Logon failure: the user has not been granted the requested logon type at this computer. ).
20100122:13.00.36.82: 00002410:ERROR:   Access denied.

Infrequently Used Logs

Windows Event Viewer log

The Windows Event Viewer contains several logs that are used less frequently than the aforementioned logs. This fact in no way diminishes their effectiveness when you are troubleshooting stored-process issues. SAS Technical Support will request these logs from you for an issue if it is necessary.

Although the event viewer contains several logs, SAS Technical Support reviews only the application log, the system log, and the security log for errors that are related to start-up and other failures in the SAS Stored Process Server (or any SAS server).

If the sassrv user ID cannot write to the Logs directory, you receive a message in this log.

If a server is stopped or started, those behaviors register in these logs. Hopefully, this review of the various logs that are related to debugging stored-process issues will assist your troubleshooting efforts.

ERROR_yyyy-mm-dd-time.log

What

This web-server log is useful when you have catastrophic failures in loading or running a stored process in a SAS web application. The syntax for this log's name is ERROR_yyyy-mm-dd-time.log.

Where

The default locations for this log are as follows:

  • Windows: SAS-configuration-directory\Lev1\Web\WebServer\logs
  • UNIX: SAS-configuration-directory/Lev1/Web/WebServer/logs

Why

Here are some reasons why you should check this log:

  • Java errors are returned in the browser when you try to load or run a stored process using the SAS Stored Process Web Application.
  • Connection errors occur between the web server and the tc Server.

Here is an example of an error that you might find in this log:

[error] (OS 10061)No connection could be made because the target machine actively refused it.  : proxy: HTTP: attempt to connect to 192.168.x.xxx:8080 (machine-name) failed

This error might occur when your servers are down or when they are restarting and are not active yet.

Example and possible cause

Let’s look at an example of how the ERROR_yyyy-mm-dd-time log can be helpful.

Suppose that you try to run a stored process through the SAS Stored Process Web Application and you cannot load any SAS 9.4 web applications after you enter your user ID and password. If you check this log, you might see errors like the following:

No connection could be made because the target machine actively refused it. : proxy: HTTP: attempt to connect to 192.168.x.xxx:8080 (machine-name) failed
 
ap_proxy_connect_backend disabling worker for (machine-name)

The secondary middle-tier node is in a clustered environment, but it configured incorrectly. For a circumvention, see SAS Note 55904, "You cannot access any SAS® 9.4 web applications when the secondary middle-tier node is in a clustered environment."

Localhost_access_log..yyyy-mm-dd.txt

What

This log shows the sequence and query strings of URLs that are submitted through the SAS Web Application Server (for all web applications that use this application server). This log lists activity sequentially and includes HTTP status codes for each URL. The syntax for this log's name is Localhost_access_log..yyyy-mm-dd.txt.

Where

The default locations for this log are as follows:

  • Windows: SAS-configuration-directory\Lev1\Web\WebAppServer\SASServer1_1\logs
  • UNIX: SAS-configuration-directory/Lev1/Web/WebAppServer/SASServer1_1/logs

Why

Here are some reasons why you should check this log:

  • A page cannot load or the URL is invalid.
  • Performance problems occur.
  • You need a good way to trace the stored-process activity after you click the Run button in web applications only.

Here is an example of a message that you might see in this log:

"POST /SASLogon/v1/tickets HTTP/1.1" 404 796

Example and possible cause

Let’s look at an example of how this log can be helpful. Suppose that you cannot log on to the SAS Stored Process Web Application. If you check this log, you might see a message like the following:

GET /SASStoredProcess/j_spring_cas_security_check?ticket=ST-9994-zpD2sFdBmayXEuoj4cya-cas HTTP/1.1" 401 802

In this example, you can see that the issue is a 401 HTTP return code.

If the servers have just been restarted, try waiting a little longer for them to start up. If that is not the issue, the server might be down. The best approach is to stop and then restart the servers. Because of dependencies, it is important to start the servers in the correct order. You can find the correct order in Overview of Server Operation, in "Chapter 6: Operating Your Servers" of the SAS® Intelligence Platform: System Administration Guide, Fourth Edition.

Access_yyyy-mm-dd-time.log

What

This log shows the sequence and query strings of URLs that are submitted through the SAS Web Server. The syntax for the name of this log is access_yyyy-mm-dd-time.log.

Where

The default locations for this log are as follows:

  • Windows: SAS-configuration-directory\Lev1\Web\WebServer\logs
  • UNIX: SAS-configuration-directory/Lev1/Web/WebServer/logs

Why

Here are some reasons why you would check this log:

  • A connection error occurs when you submit a stored process.
  • Java errors occur in the browser.
  • When you evaluate a performance problem, timestamps in the log confirm when the web server received the request and what was in the request.
  • The output that is produced by the stored process does not match the expected output based on the prompt selections that are available when you submit the stored process.

Here is an example of a message that you might see in this log:

"GET /SASTheme_default/themes/ThemeXMLFiles.config HTTP/1.1" 503 299

This error might occur because the servers are down or are in the process of restarting and are not active yet.

Example and possible cause

Let’s look at an example of how the access_yyyy-mm-dd-time log can be helpful.

Suppose that you are trying to run a stored process through the SAS web application and you receive a connection error. If you check this log, you might see a message like the following:

"GET /SASLogon/proxy?pgt=TGT-6-aGakal9b2VGBg3dnNTbbwiVALOWqBSem9E3cVWehDD35vegmxI-cas&targetService=http%3A%2F%2FLazySecurityContext HTTP/1.1" 502 407

The message above shows a 502 HTTP return code. This error indicates that the server, while acting as a gateway or proxy, received an invalid response from the upstream server. If the servers were just restarted, try waiting a little longer for them to start back up. If that is not the issue, then a server might be down. The best approach is to stop and restart the servers. Because of dependencies, it is important to start the servers in the correct order. You can find the correct order in Overview of Server Operation, in "Chapter 6: Operating Your Servers" of the SAS® Intelligence Platform: System Administration Guide, Fourth Edition.

Server.log

What

This log is helpful if a stored-process web application generates an HTPP, browser, or generic error in the browser when it loads a page or results that are returned from a stored process.

Where

The default locations for this log are as follows:

  • Windows: SAS-configuration-directory\Lev1\Web\WebAppServer\SASServer1_1\logs
  • UNIX: SAS-configuration-directory/Lev1/Web/WebAppServer/SASServer1_1/logs

Why

Here are some reasons why you would check this log:

  • The SAS Stored Processes web application is not working.
  • Requests time out.
  • A configuration change is made to one of the web applications (for example, an increase to the time-out for the stored-process web application).
  • A generic error is displayed in the SAS Stored Processes web application when you run a stored process.

Here is an example of a message that you might find in this log:

java.io.IOException: Cannot bind to URL

One possible reason for this type of error is network issues at the site where the stored process is run.

Example and possible cause

Let’s look at an example of how the server.log file can be helpful.

Suppose that you want to run a stored process through the SAS Web Application and you receive a generic error that says The system is experiencing problems. Please contact your system administrator. If you check this log, you might see a message like the following:

ERROR (ContainerBackgroundProcessor[StandardEngine[Catalina]]) [org.apache.catalina.core.ContainerBase] Unexpected death of background thread ContainerBackgroundProcessor[StandardEngine[Catalina]]
java.lang.OutOfMemoryError: Java heap space

There is insufficient memory available to process the request. As a possible workaround, you need to modify the setenv.bat file that resides on Windows in SAS-configuration-directory\Lev1\Web\Webappserver\Sasserver1_1\bin\ or the setenv.sh in SAS-configuration-directory/Lev1/Web/WebAppServer/Sasserver1_1/bin/ on UNIX. You need to edit the JVM_OPTS value by changing the -Xmx4096m -Xms1024m parameter to the following:

-Xmx8092m -Xms8092m

Making this change requires the restart of the SAS Web Application Server if only the webappserver script is updated.

Conclusion

Hopefully, this review of logs that are related to debugging stored-process issues will assist your troubleshooting efforts. When you request help from SAS Technical Support, these are some of the logs that you will be asked to send so that Technical Support can better determine the cause of your problem.

Learn more

Debugging a stored-process problem was published on SAS Users.

8月 172021
 

What happens if you need to edit graph output files from SAS in a different application (for example, Microsoft Word)? It is not recommended that you edit your SAS graph output outside of SAS, but if you must do so, this article discusses the graphics output options that you need to use.

Understanding the EMF graph output types

To create graphics output that is editable, you need to create your graphics output as EMF (Enhanced Metafile Format) graph output. The EMF graph format is a vector-based graphics format. Formats such as PNG, GIF, JPEG, and TIFF are bitmap image formats and, typically, bitmap image formats cannot be edited.

You can either create a stand-alone EMF graph output file or embed your EMF graph output inside an RTF document by using the ODS RTF destination. The EMF graph format is the default graph format when you want to create graphics output with the ODS RTF destination.

By design, the default EMF graph output that SAS creates is in an EMF Plus (EMF+) format. However, this type of EMF graph output is not editable. To create an EMF graph output that you can edit, you must create your EMF graphics output in a format known as EMF Dual format. This format combines EMF Plus output and traditional EMF graph output in a single graph file.

Creating EMF Dual graph output with the SAS/GRAPH® procedures

If you are using a SAS/GRAPH procedure (such as GPLOT or GCHART), you can create EMF Dual graph output by specifying the DEVICE=EMFDUAL option in the GOPTIONS statement:

goptions device=emfdual;

When you use the EMFDUAL device driver to write a stand-alone EMF graph file to disk, use code similar to the following:

ods _all_ close; 
ods listing; 
filename grafout "\file-path\file-name.emf"; 
goptions device=emfdual gsfname=grafout;
/* Your SAS/GRAPH procedure code goes here */

When you use the EMFDUAL device driver to write an RTF document to disk, use code similar to the following:

goptions device=emfdual;
ods _all_ close; 
ods rtf file="\file-path\file-name.rtf"; 
/* Your SAS/GRAPH procedure code goes here */
ods rtf close; 
ods listing;

Creating EMF Dual graph output with ODS Graphics and the SAS SG procedures

If you are using ODS Graphics or the SAS statistical graphics (SG) procedures (such as SGPLOT), you can create EMF Dual graph output by adding the following REGISTRY procedure code to the top of your existing code:

%let workdir=%trim(%sysfunc(pathname(work)));
data _null_;
   file "&workdir./emf94.sasxreg";
   put '[CORE\PRINTING\PRINTERS\EMF\ADVANCED]';
   put '"Description"="Enhanced Metafile Format"';
   put '"Metafile Type"="DUAL"';
run;
proc registry import="&workdir./emf94.sasxreg";
run;

Then, specify the OUTPUTFMT=EMF option in the ODS GRAPHICS statement before the procedure step. Here is an example:

ods graphics / outputfmt=emf;

Understanding issues that might occur

The EMF format does not support data skins or transparency. Therefore, if your SAS code creates graphics output using data skins or transparency, keep in mind that the graph output is created as an image and the following note is written to the log:

NOTE: The graph in the RTF destination will be rendered as an image due to the use of transparency and data skin.

To create editable vector-based graphics output, you need to modify your code to not use data skins or transparency.

Also, graphs that use dashed lines cannot be edited outside of SAS. In this case, you need to modify your SAS code or the ODS style so that the graph is created with solid lines instead of dashed lines.

Conclusion

Instead of editing a graph outside of SAS, it is recommended that you modify your graph by using statements and options in the SAS code itself. If you need assistance about how to do that, contact SAS Technical Support.

See also:

How to create EMF graph output files that can be edited outside of your SAS® program was published on SAS Users.