-
Notifications
You must be signed in to change notification settings - Fork 0
/
Redirect Log.step
1 lines (1 loc) · 26.8 KB
/
Redirect Log.step
1
{"creationTimeStamp":"2024-05-25T19:39:41.837Z","modifiedTimeStamp":"2024-05-25T21:33:17.014Z","createdBy":"viya_admin","modifiedBy":"viya_admin","name":"Redirect Log.step","displayName":"Redirect Log.step","localDisplayName":"Redirect Log.step","properties":{},"links":[{"method":"GET","rel":"self","href":"/dataFlows/steps/053868b1-331e-4e9b-a44d-2282dfa99fe9","uri":"/dataFlows/steps/053868b1-331e-4e9b-a44d-2282dfa99fe9","type":"application/vnd.sas.data.flow.step"},{"method":"GET","rel":"alternate","href":"/dataFlows/steps/053868b1-331e-4e9b-a44d-2282dfa99fe9","uri":"/dataFlows/steps/053868b1-331e-4e9b-a44d-2282dfa99fe9","type":"application/vnd.sas.data.flow.step.summary"},{"method":"GET","rel":"up","href":"/dataFlows/steps","uri":"/dataFlows/steps","type":"application/vnd.sas.collection","itemType":"application/vnd.sas.data.flow.step.summary"},{"method":"PUT","rel":"update","href":"/dataFlows/steps/053868b1-331e-4e9b-a44d-2282dfa99fe9","uri":"/dataFlows/steps/053868b1-331e-4e9b-a44d-2282dfa99fe9","type":"application/vnd.sas.data.flow.step","responseType":"application/vnd.sas.data.flow.step"},{"method":"DELETE","rel":"delete","href":"/dataFlows/steps/053868b1-331e-4e9b-a44d-2282dfa99fe9","uri":"/dataFlows/steps/053868b1-331e-4e9b-a44d-2282dfa99fe9"},{"method":"POST","rel":"copy","href":"/dataFlows/steps/053868b1-331e-4e9b-a44d-2282dfa99fe9/copy","uri":"/dataFlows/steps/053868b1-331e-4e9b-a44d-2282dfa99fe9/copy","responseType":"application/vnd.sas.data.flow.step"},{"method":"GET","rel":"transferExport","href":"/dataFlows/steps/053868b1-331e-4e9b-a44d-2282dfa99fe9","uri":"/dataFlows/steps/053868b1-331e-4e9b-a44d-2282dfa99fe9","responseType":"application/vnd.sas.transfer.object"},{"method":"PUT","rel":"transferImportUpdate","href":"/dataFlows/steps/053868b1-331e-4e9b-a44d-2282dfa99fe9","uri":"/dataFlows/steps/053868b1-331e-4e9b-a44d-2282dfa99fe9","type":"application/vnd.sas.transfer.object","responseType":"application/vnd.sas.summary"}],"metadataVersion":0.0,"version":2,"type":"code","flowMetadata":{"inputPorts":[],"outputPorts":[{"name":"outputTable","displayName":"outputTable","localDisplayName":"outputTable","minEntries":1,"maxEntries":1,"defaultEntries":0,"type":"table","supportsView":false,"requiresStructure":false}]},"ui":"{\n\t\"showPageContentOnly\": true,\n\t\"pages\": [\n\t\t{\n\t\t\t\"id\": \"page1\",\n\t\t\t\"type\": \"page\",\n\t\t\t\"label\": \"Parameters\",\n\t\t\t\"children\": [\n\t\t\t\t{\n\t\t\t\t\t\"id\": \"section2\",\n\t\t\t\t\t\"type\": \"section\",\n\t\t\t\t\t\"label\": \"Input parameters\",\n\t\t\t\t\t\"open\": true,\n\t\t\t\t\t\"visible\": \"\",\n\t\t\t\t\t\"children\": [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"redirectOperation\",\n\t\t\t\t\t\t\t\"type\": \"dropdown\",\n\t\t\t\t\t\t\t\"label\": \"Select redirection operation:\",\n\t\t\t\t\t\t\t\"items\": [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"value\": \"log\",\n\t\t\t\t\t\t\t\t\t\"label\": \"Redirect log file\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"value\": \"output\",\n\t\t\t\t\t\t\t\t\t\"label\": \"Redirect procedure output\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"value\": \"both\",\n\t\t\t\t\t\t\t\t\t\"label\": \"Redirect log and output\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"value\": \"default\",\n\t\t\t\t\t\t\t\t\t\"label\": \"Reassign to default location\"\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\"required\": true,\n\t\t\t\t\t\t\t\"placeholder\": \"\",\n\t\t\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"logLocationPath\",\n\t\t\t\t\t\t\t\"type\": \"path\",\n\t\t\t\t\t\t\t\"label\": \"Provide location to redirect log file:\",\n\t\t\t\t\t\t\t\"pathtype\": \"file\",\n\t\t\t\t\t\t\t\"placeholder\": \"\",\n\t\t\t\t\t\t\t\"required\": false,\n\t\t\t\t\t\t\t\"visible\": [\n\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\"$redirectOperation\",\n\t\t\t\t\t\t\t\t\t\"=\",\n\t\t\t\t\t\t\t\t\t\"log\"\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\"|\",\n\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\"$redirectOperation\",\n\t\t\t\t\t\t\t\t\t\"=\",\n\t\t\t\t\t\t\t\t\t\"both\"\n\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\"enabled\": [\n\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\"$redirectOperation\",\n\t\t\t\t\t\t\t\t\t\"=\",\n\t\t\t\t\t\t\t\t\t\"log\"\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\"|\",\n\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\"$redirectOperation\",\n\t\t\t\t\t\t\t\t\t\"=\",\n\t\t\t\t\t\t\t\t\t\"both\"\n\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"outputLocationPath\",\n\t\t\t\t\t\t\t\"type\": \"path\",\n\t\t\t\t\t\t\t\"label\": \"Provide location to redirect procedure output:\",\n\t\t\t\t\t\t\t\"pathtype\": \"file\",\n\t\t\t\t\t\t\t\"placeholder\": \"\",\n\t\t\t\t\t\t\t\"required\": false,\n\t\t\t\t\t\t\t\"visible\": [\n\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\"$redirectOperation\",\n\t\t\t\t\t\t\t\t\t\"=\",\n\t\t\t\t\t\t\t\t\t\"output\"\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\"|\",\n\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\"$redirectOperation\",\n\t\t\t\t\t\t\t\t\t\"=\",\n\t\t\t\t\t\t\t\t\t\"both\"\n\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\"enabled\": [\n\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\"$redirectOperation\",\n\t\t\t\t\t\t\t\t\t\"=\",\n\t\t\t\t\t\t\t\t\t\"output\"\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\"|\",\n\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\"$redirectOperation\",\n\t\t\t\t\t\t\t\t\t\"=\",\n\t\t\t\t\t\t\t\t\t\"both\"\n\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t}\n\t\t\t\t\t]\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"id\": \"section1\",\n\t\t\t\t\t\"type\": \"section\",\n\t\t\t\t\t\"label\": \"Output specification\",\n\t\t\t\t\t\"open\": true,\n\t\t\t\t\t\"visible\": \"\",\n\t\t\t\t\t\"children\": [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"outputTable\",\n\t\t\t\t\t\t\t\"type\": \"outputtable\",\n\t\t\t\t\t\t\t\"label\": \"Provide reference dataset:\",\n\t\t\t\t\t\t\t\"required\": true,\n\t\t\t\t\t\t\t\"placeholder\": \"WORK.LOG_AND_OUTPUT_REDIRECTION\",\n\t\t\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"text2\",\n\t\t\t\t\t\t\t\"type\": \"text\",\n\t\t\t\t\t\t\t\"text\": \"Provide an output table to be used as a reference dataset for all redirection operations performed within a process.\",\n\t\t\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t\t\t}\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"id\": \"about\",\n\t\t\t\"type\": \"page\",\n\t\t\t\"label\": \"About\",\n\t\t\t\"children\": [\n\t\t\t\t{\n\t\t\t\t\t\"id\": \"about_description\",\n\t\t\t\t\t\"type\": \"text\",\n\t\t\t\t\t\"text\": \"Redirect Log\\n=========\\n\\nThis custom step redirects log & procedural output of downstream SAS programs to specified external files, also reassigning them to the default location when needed. \\n\\nThis will prove useful for scenarios requiring automated generation of log or output files. For example, this step can be used to fulfill governance, regulatory and compliance objectives in industries such as banking and life sciences.\\n\",\n\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"id\": \"about_parameters\",\n\t\t\t\t\t\"type\": \"section\",\n\t\t\t\t\t\"label\": \"Parameters\",\n\t\t\t\t\t\"open\": true,\n\t\t\t\t\t\"visible\": \"\",\n\t\t\t\t\t\"children\": [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"parameters_input\",\n\t\t\t\t\t\t\t\"type\": \"section\",\n\t\t\t\t\t\t\t\"label\": \"Input parameters\",\n\t\t\t\t\t\t\t\"open\": true,\n\t\t\t\t\t\t\t\"visible\": \"\",\n\t\t\t\t\t\t\t\"children\": [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"id\": \"input_parameters_text\",\n\t\t\t\t\t\t\t\t\t\"type\": \"text\",\n\t\t\t\t\t\t\t\t\t\"text\": \"1. Redirection operation (drop-down list, required): choose whether to redirect only the log, only the output, both log and output, or to reassign to default location.\\n\\n2. Log file location (file selector, enabled if log redirection is selected): provide a path to a log file on the file system. The path should be writeable.\\n\\n3. Output file location (file selector, enabled if output redirection is selected): provide a path on the file system. The path should be writeable.\\n\",\n\t\t\t\t\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"parameters_output_specs\",\n\t\t\t\t\t\t\t\"type\": \"section\",\n\t\t\t\t\t\t\t\"label\": \"Output specifications\",\n\t\t\t\t\t\t\t\"open\": false,\n\t\t\t\t\t\t\t\"visible\": \"\",\n\t\t\t\t\t\t\t\"children\": [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"id\": \"output_parameters_text\",\n\t\t\t\t\t\t\t\t\t\"type\": \"text\",\n\t\t\t\t\t\t\t\t\t\"text\": \"- Reference dataset (output port, required): connect a SAS dataset or CAS table to the output port of this custom step, to hold references to the redirected files. A timestamp is also added to indicate when this redirection occurred.\\n\\nEvery run of this step appends information to the reference dataset. The dataset is created if it does not exist the first time.\",\n\t\t\t\t\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t}\n\t\t\t\t\t]\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"id\": \"section_gotchas\",\n\t\t\t\t\t\"type\": \"section\",\n\t\t\t\t\t\"label\": \"Common \\\"gotchas\\\"\",\n\t\t\t\t\t\"open\": true,\n\t\t\t\t\t\"visible\": \"\",\n\t\t\t\t\t\"children\": [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"text1\",\n\t\t\t\t\t\t\t\"type\": \"text\",\n\t\t\t\t\t\t\t\"text\": \"When used with improper understanding or familiarity, proc printto (the driving functionality in this custom step) might lead to confusion or errors. Please be aware of the following:\\n\\n1. Log / output redirection are not perfect substitutes for ODS HTML / Excel etc. The purpose behind redirection is for creating separate, specified log or listing files for persistence or communication. ODS HTML (or ODS EXCEL and other equivalents) perform a similar function but offer more functionality such as formatting etc.\\n\\n2. Output redirection does not automatically extend to plots, i.e. charts. You'll find upon examination that the log may provide an entry stating where the plot has been saved. Use the ODS listing command to redirect graphics. See https://communities.sas.com/t5/Graphics-Programming/Specify-SGPlot-png-output-location/td-p/622251 for a discussion.\\n\\n3. When used within a SAS Studio Flow, log redirection will affect the status of nodes in a flow. You will find that even when nodes are run successfully, a redirected log may cause the green tick mark to not appear. Please be aware of the same.\\n\\n4. This is NOT meant to be a log / output suppression mechanism for SAS Studio Flows. This step neither guarantees nor intends to change the behaviour of product features and configuration in SAS Studio Flows or Steps. \",\n\t\t\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t\t\t}\n\t\t\t\t\t]\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"id\": \"about_runtimecontrol\",\n\t\t\t\t\t\"type\": \"section\",\n\t\t\t\t\t\"label\": \"Run-time Control\",\n\t\t\t\t\t\"open\": 0,\n\t\t\t\t\t\"visible\": \"\",\n\t\t\t\t\t\"children\": [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"runtimecontrol_text\",\n\t\t\t\t\t\t\t\"type\": \"text\",\n\t\t\t\t\t\t\t\"text\": \"Note: Run-time control is optional. You may choose whether to execute the main code of this step or not, based on upstream conditions set by earlier SAS programs. This includes nodes run prior to this custom step earlier in a SAS Studio Flow, or a previous program in the same session.\\n\\nRefer this blog (https://communities.sas.com/t5/SAS-Communities-Library/Switch-on-switch-off-run-time-control-of-SAS-Studio-Custom-Steps/ta-p/885526) for more details on the concept.\\n\\nThe following macro variable,\\n\\n_rl_run_trigger\\n\\nwill initialize with a value of 1 by default, indicating an \\\"enabled\\\" status and allowing the custom step to run.\\n\\nIf you wish to control execution of this custom step, include code in an upstream SAS program to set this variable to 0. This \\\"disables\\\" execution of the custom step.\\n\\nTo \\\"disable\\\" this step, run the following code upstream:\\n\\n%global _rl_run_trigger;\\n%let _rl_run_trigger =0;\\n\\nTo \\\"enable\\\" this step again, run the following (it's assumed that this has already been set as a global variable):\\n\\n%let _rl_run_trigger =1;\\n\\nIMPORTANT: Be aware that disabling this step means that none of its main execution code will run, and any downstream code which was dependent on this code may fail. Change this setting only if it aligns with the objective of your SAS Studio program.\",\n\t\t\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t\t\t}\n\t\t\t\t\t]\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"id\": \"about_documentation\",\n\t\t\t\t\t\"type\": \"section\",\n\t\t\t\t\t\"label\": \"Documentation\",\n\t\t\t\t\t\"open\": 0,\n\t\t\t\t\t\"visible\": \"\",\n\t\t\t\t\t\"children\": [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"documentation_text\",\n\t\t\t\t\t\t\t\"type\": \"text\",\n\t\t\t\t\t\t\t\"text\": \"1. Documentation for the Proc Printto statement which redirects log and procedure output: https://go.documentation.sas.com/doc/en/pgmsascdc/default/proc/p1hwvc03z4tqlkn1owzhzo8e7ulu.htm\\n\\n2. This custom step makes use of a GOTO statement, a practice that purists consider 'bad' programming. At the same time, GOTO can be tolerated in certain situations, as discussed in the following blog (and hopefully valid in this context): https://smartbear.com/blog/goto-still-has-a-place-in-modern-programming-no-re/. Note that there are many disussions on GOTO online, and this blog is presented as just one example.\\n\\n3. For a discussion on alternatives for graphs and charts, see: https://communities.sas.com/t5/Graphics-Programming/Specify-SGPlot-png-output-location/td-p/622251\",\n\t\t\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t\t\t}\n\t\t\t\t\t]\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"id\": \"version_text\",\n\t\t\t\t\t\"type\": \"text\",\n\t\t\t\t\t\"text\": \"Version: 1.0 (25MAY2024)\",\n\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"id\": \"contact_text\",\n\t\t\t\t\t\"type\": \"text\",\n\t\t\t\t\t\"text\": \"Created/contact: \\n\\n- Lou Galway (lou.galway@sas.com)\\n- Sundaresh Sankaran (sundaresh.sankaran@sas.com)\\n\",\n\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t}\n\t\t\t]\n\t\t}\n\t],\n\t\"syntaxversion\": \"1.3.0\",\n\t\"values\": {\n\t\t\"redirectOperation\": {\n\t\t\t\"value\": \"default\",\n\t\t\t\"label\": \"Reassign to default location\"\n\t\t},\n\t\t\"logLocationPath\": \"\",\n\t\t\"outputLocationPath\": \"\",\n\t\t\"outputTable\": {\n\t\t\t\"library\": \"\",\n\t\t\t\"table\": \"\"\n\t\t}\n\t}\n}","templates":{"SAS":"/* SAS templated code goes here */\n\n/*-----------------------------------------------------------------------------------------*\n START MACRO DEFINITIONS.\n*------------------------------------------------------------------------------------------*/\n\n/* -------------------------------------------------------------------------------------------* \n Macro to initialize a run-time trigger global macro variable to run SAS Studio Custom Steps. \n A value of 1 (the default) enables this custom step to run. A value of 0 (provided by \n upstream code) sets this to disabled.\n\n Input:\n 1. triggerName: The name of the runtime trigger you wish to create. Ensure you provide a \n unique value to this parameter since it will be declared as a global variable.\n\n Output:\n 2. &triggerName : A global variable which takes the name provided to triggerName.\n\n Also at: https://github.com/SundareshSankaran/sas_utility_programs/blob/main/code/Create_Run_Time_Trigger/macro_create_runtime_trigger.sas\n*-------------------------------------------------------------------------------------------- */\n\n%macro _create_runtime_trigger(triggerName);\n\n %global &triggerName.;\n\n %if %sysevalf(%superq(&triggerName.)=, boolean) %then %do;\n \n %put NOTE: Trigger macro variable &triggerName. does not exist. Creating it now.;\n %let &triggerName.=1;\n\n %end;\n\n%mend _create_runtime_trigger;\n\n\n/* -----------------------------------------------------------------------------------------* \n Macro to create an error flag for capture during code execution.\n\n Input:\n 1. errorFlagName: The name of the error flag you wish to create. Ensure you provide a \n unique value to this parameter since it will be declared as a global variable.\n 2. errorFlagDesc: The name of an error flag description variable to hold the error \n description.\n\n Output:\n 1. &errorFlagName : A global variable which takes the name provided to errorFlagName.\n 2. &errorFlagDesc : A global variable which takes the name provided to errorFlagDesc.\n\n Also available at: \n https://github.com/SundareshSankaran/sas_utility_programs/blob/main/code/Error%20Flag%20Creation/macro_create_error_flag.sas\n*------------------------------------------------------------------------------------------ */\n\n%macro _create_error_flag(errorFlagName, errorFlagDesc);\n\n %global &errorFlagName.;\n %global &errorFlagDesc.;\n %let &errorFlagName.=0;\n %let &errorFlagDesc. = No errors reported so far;\n \n%mend _create_error_flag;\n\n\n/* -----------------------------------------------------------------------------------------* \n Macro to identify whether a given folder location provided from a \n SAS Studio Custom Step folder selector happens to be a SAS Content folder\n or a folder on the filesystem (SAS Server).\n\n Input:\n 1. pathReference: A path reference provided by the file or folder selector control in \n a SAS Studio Custom step.\n\n Output:\n 1. _path_identifier: Set inside macro, a global variable indicating the prefix of the \n path provided.\n\n Also available at: https://raw.githubusercontent.com/SundareshSankaran/sas_utility_programs/main/code/Identify%20SAS%20Content%20or%20Server/macro_identify_sas_content_server.sas\n\n*------------------------------------------------------------------------------------------ */\n\n%macro _identify_content_or_server(pathReference);\n %global _path_identifier;\n data _null_;\n call symput(\"_path_identifier\", scan(\"&pathReference.\",1,\":\",\"MO\"));\n run;\n %put NOTE: _path_identifier is &_path_identifier. ;\n%mend _identify_content_or_server;\n\n\n/* -----------------------------------------------------------------------------------------* \n Macro to extract the path provided from a SAS Studio Custom Step file or folder selector.\n\n Input:\n 1. pathReference: A path reference provided by the file or folder selector control in \n a SAS Studio Custom step.\n\n Output:\n 1. _sas_folder_path: Set inside macro, a global variable containing the path.\n\n Also available at: https://raw.githubusercontent.com/SundareshSankaran/sas_utility_programs/main/code/Extract%20SAS%20Folder%20Path/macro_extract_sas_folder_path.sas\n\n*------------------------------------------------------------------------------------------ */\n\n%macro _extract_sas_folder_path(pathReference);\n\n %global _sas_folder_path;\n\n data _null_;\n call symput(\"_sas_folder_path\", scan(\"&pathReference.\",2,\":\",\"MO\"));\n run;\n\n%mend _extract_sas_folder_path;\n\n/* -----------------------------------------------------------------------------------------* \n Macro to handle the redirection of a log file.\n*------------------------------------------------------------------------------------------ */\n%macro _rl_redirect_log;\n %_identify_content_or_server(&logLocationPath.);\n %if \"&_path_identifier.\" = \"sascontent\" %then %do;\n data _null_;\n call symputx(\"_rl_error_flag\",1);\n call symput(\"_rl_error_desc\",\"Provide a log file path located on the file system.\");\n run;\n %end;\n %else %do;\n data _null_;\n call symput(\"_rl_error_desc\",\"Redirected log file is located on the file system.\");\n run;\n %end;\n %if &_rl_error_flag.=0 %then %do;\n %_extract_sas_folder_path(&logLocationPath.);\n %put NOTE: SAS Folder path is &_sas_folder_path.;\n data _null_;\n call symput(\"logLocation\",'\"'||\"&_sas_folder_path.\"||'\"');\n run;\n %let _sas_folder_path=;\n %end;\n\n%mend _rl_redirect_log;\n\n/* -----------------------------------------------------------------------------------------* \n Macro to handle the redirection of an output file.\n*------------------------------------------------------------------------------------------ */\n%macro _rl_redirect_output;\n %_identify_content_or_server(&outputLocationPath.);\n %if \"&_path_identifier.\" = \"sascontent\" %then %do;\n data _null_;\n call symputx(\"_rl_error_flag\",1);\n call symput(\"_rl_error_desc\",\"Provide an output file path located on the file system.\");\n run;\n %end;\n %else %do;\n data _null_;\n call symput(\"_rl_error_desc\",\"Redirected output file is located on the file system.\");\n run;\n %end;\n %if &_rl_error_flag.=0 %then %do;\n %_extract_sas_folder_path(&outputLocationPath.);\n %put NOTE: SAS Folder path is &_sas_folder_path.;\n data _null_;\n call symput(\"outputLocation\",'\"'||\"&_sas_folder_path.\"||'\"');\n run;\n %let _sas_folder_path=;\n %end;\n\n%mend _rl_redirect_output;\n\n/* -----------------------------------------------------------------------------------------* \n Macro to write redirection events to an output dataset.\n*------------------------------------------------------------------------------------------ */\n%macro _rl_write_output_dataset(operation, location);\n %put &location.;\n\n %if %sysfunc(exist(&outputTable.)) %then %do;\n %put NOTE: Output dataset exists;\n %end;\n %else %do;\n data &outputTable.;\n length operation $8. location $1024. update_dttm 8.;\n format update_dttm datetime20.;\n informat update_dttm datetime20.;\n run;\n %end;\n\n\n data WORK.__temp_location;\n length operation $8. location $1024. update_dttm 8.;\n format update_dttm datetime20.;\n informat update_dttm datetime20.;\n\n operation = \"&operation.\";\n location = \"&location.\";\n update_dttm = datetime() ;\n run;\n\n proc append data=work.__temp_location base=&outputTable. force;\n quit;\n\n proc datasets lib= work;\n delete __temp_location;\n quit;\n\n%mend _rl_write_output_dataset;\n\n\n/*-----------------------------------------------------------------------------------------*\n EXECUTION CODE MACRO \n\n _rl prefix stands for Redirect Log\n\n Note: This code block is a variation from the normal way the run-time control's used in \n other custom steps. A redirection of log leads to the program exiting the %do-%end\n block in an unclean manner. To avoid this, we use a %goto statement, usually \n considered undesirable, but appropriate for situations such as these (to exit a\n function cleanly).\n*------------------------------------------------------------------------------------------*/\n\n%macro _rl_execution_code;\n\n %if &_rl_run_trigger. = 0 %then %do;\n %put NOTE: This step has been disabled. Nothing to do.;\n %goto exit;\n %end;\n \n\n %put NOTE: Starting main execution code;\n\n/*-----------------------------------------------------------------------------------------*\n Create an error flag. \n*------------------------------------------------------------------------------------------*/\n\n %_create_error_flag(_rl_error_flag, _rl_error_desc);\n\n %put NOTE: Error flag created;\n\n\n %global logLocation;\n %global outputLocation;\n %let logLocation=LOG;\n %let outputLocation=PRINT;\n\n/*-----------------------------------------------------------------------------------------*\n If the redirect macro already exists, then check status and perform operation accordingly.\n Else, inform user to run the reassignment (default) operation. \n*------------------------------------------------------------------------------------------*/\n\n %if \"&redirectOperation.\" = \"log\" %then %do;\n %_rl_redirect_log;\n %if &_rl_error_flag.=0 %then %do;\n %_rl_write_output_dataset(&redirectOperation., \"&logLocation.\");\n %end;\n %end;\n %else %if \"&redirectOperation.\" = \"output\" %then %do;\n %_rl_redirect_output;\n %if &_rl_error_flag.=0 %then %do;\n %_rl_write_output_dataset(&redirectOperation., \"&outputLocation.\");\n %end;\n %end;\n %else %if \"&redirectOperation.\" = \"both\" %then %do;\n %_rl_redirect_log;\n %_rl_redirect_output;\n %if &_rl_error_flag.=0 %then %do;\n %_rl_write_output_dataset(&redirectOperation._log, \"&logLocation.\");\n %_rl_write_output_dataset(&redirectOperation._output, \"&outputLocation.\");\n %end;\n %end;\n %else %if \"&redirectOperation.\" = \"default\" %then %do;\n %_rl_write_output_dataset(&redirectOperation., default_location);\n %end;\n\n proc printto LOG=&logLocation. PRINT=&outputLocation. ;\n run;\n\n\n%exit: %mend _rl_execution_code;\n\n/*-----------------------------------------------------------------------------------------*\n EXECUTION CODE\n The execution code is controlled by the trigger variable defined in this custom step. This\n trigger variable is in an \"enabled\" (value of 1) state by default, but in some cases, as \n dictated by logic, could be set to a \"disabled\" (value of 0) state.\n\n The execution below is a variation from the normal use of a run-time trigger. Refer note for \n %_rl_execution_code.\n*------------------------------------------------------------------------------------------*/\n/*-----------------------------------------------------------------------------------------*\n Create run-time trigger. \n*------------------------------------------------------------------------------------------*/\n\n%_create_runtime_trigger(_rl_run_trigger);\n\n/*-----------------------------------------------------------------------------------------*\n Execute \n*------------------------------------------------------------------------------------------*/\n \n%_rl_execution_code;\n\n%put NOTE: Final summary;\n%put NOTE: Status of error flag - &_rl_error_flag. ;\n%put NOTE: Error desc - &_rl_error_desc. ;\n\n/*-----------------------------------------------------------------------------------------*\n Clean up existing macro variables and macro definitions.\n*------------------------------------------------------------------------------------------*/\n\n%if %symexist(_sas_folder_path) %then %do;\n %symdel _sas_folder_path;\n%end;\n%if %symexist(_path_identifier) %then %do;\n %symdel _path_identifier;\n%end;\n%if %symexist(_rl_error_flag) %then %do;\n %symdel _rl_error_flag;\n%end;\n%if %symexist(_rl_error_desc) %then %do;\n %symdel _rl_error_desc;\n%end;\n%if %symexist(_rl_run_trigger) %then %do;\n %symdel _rl_run_trigger;\n%end;\n\n%sysmacdelete _rl_redirect_log;\n%sysmacdelete _rl_redirect_output;\n%sysmacdelete _rl_execution_code;\n%sysmacdelete _create_runtime_trigger;\n%sysmacdelete _identify_content_or_server;\n%sysmacdelete _extract_sas_folder_path;\n%sysmacdelete _create_error_flag;\n\n"}}