Log Rotaion on IQService using PowerShell script is failing

Which IIQ version are you inquiring about?

Version 8.3

Share all details related to your problem, including any error messages you may have received.

Hi All,

I am new in sailpoint IIQ
I am trying to rename IQService logs using the PowerShell script but I am facing issues. Below is my PowerShell Script file:

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE Rule PUBLIC "sailpoint.dtd" "sailpoint.dtd">
<Rule language="beanshell" name="Rule_Script_PowerShell_LogRotation" >
  <Attributes>
    <Map>
      <entry key="ObjectOrientedScript" value="true"/>
      <entry key="disabled" value="false"/>
      <entry key="extension" value=".ps1"/>
      <entry key="program" value="powershell.exe"/>
      <entry key="timeout" value="300"/>
    </Map>
  </Attributes>
  <Source><![CDATA[ 
	start-transcript -Path "D:\PSLogs\MyTestLog.txt" -append
	Write-Host "Start Rule :: Rule_Script_PowerShell_LogRotation"
    # Get the File
	$File = Get-Item D:\PSLogs\SailPointPSLog.txt
	 
	# Get the File Size
	$size = $File.Length
	Write-Host $size
	$sizeKB = $size/1KB
	$sizeMB = $size/1MB
	if($sizeMB -gt 500MB){
		Write-Host "File size is: $sizeMB"
		$dateStr = (Get-Date).ToString("yyyyMMddhhmmss")
		Get-Childitem "D:\PSLogs\SailPointPSLog.txt" | Rename-Item -NewName {(-join($_.BaseName, "_", $dateStr, ".txt"))}
		Write-Host "File successfully renamed."
	} elseif{
		Write-Host "File size is less than 500MB"
	}
	
	Stop-Transcript
  ]]></Source>
</Rule>

I have created below Rule to execute the above script :

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE Rule PUBLIC "sailpoint.dtd" "sailpoint.dtd">
<Rule language="beanshell" name="Rule_Log_Rotation">
  <Signature>
    <Inputs>      
      <Argument name="log">
        <Description>
          The log object associated with the SailPointContext.
        </Description>
      </Argument>
      <Argument name="context">
        <Description>
          A sailpoint.api.SailPointContext object that can be used to query the database if necessary.
        </Description>
      </Argument>
    </Inputs>
    <Returns>
      <Argument name="finalOutputResponse">
        <Description>
          Output Response for Log Rotation
        </Description>
      </Argument>
    </Returns>
  </Signature>
  <Source><![CDATA[

  import java.io.*;  
  import java.net.*;  
  import java.util.*;  
  import org.apache.commons.logging.Log;  
  import org.apache.commons.logging.LogFactory;  
  import sailpoint.api.*;  
  import sailpoint.object.*;  
  import sailpoint.tools.GeneralException;  
  import sailpoint.tools.Message;  
  import sailpoint.tools.Util;  
  import sailpoint.connector.*;  
  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogFactory;
  import org.apache.log4j.Logger;

  Log logger = LogFactory.getLog("Rule_Log_Rotation");
  logger.error("Start of Rule_Log_Rotation");  
  
  public String rotateLog (String TFAYD_IQSERVICE_HOST, int TFAYD_IQSERVICE_PORT){
    logger.error("Prinnt 1");
    String outputResponse = null;   
    try { 	  
      RpcResponse iqserviceResponse = executeCmdLet(TFAYD_IQSERVICE_HOST,TFAYD_IQSERVICE_PORT,"Rule_Script_PowerShell_LogRotation");
      logger.error("Rule_Log_Rotation_updated: iqserviceResponse : "+iqserviceResponse);
      if(iqserviceResponse.getMessages() != null && iqserviceResponse.getMessages().get(0).equalsIgnoreCase("Success!"))
        outputResponse = "Successfully Created";
      else
        outputResponse = "Failure";
    } catch (Exception e){  
      logger.error("Error Response in Catch"+e.getMessage());
      outputResponse = e.getMessage();
    } finally {      
      logger.error("End of Rule_Log_Rotation");
    }
    logger.error("Rule_Log_Rotation_updated: outputResponse : "+outputResponse);
    return outputResponse;
  }
  
  public RpcResponse executeCmdLet(String iqServiceHost,int iqServicePort,String ruleName) throws Exception {  
	logger.error("Prinnt 2");
    HashMap dataMap = new HashMap();  
    
    Rule ruleObj=null;
    if(ruleName.equals("Rule_Script_PowerShell_LogRotation")){
      logger.error("Rule_Log_Rotation: Entry into IF loop : if Rule name is Rule_Script_PowerShell_LogRotation");
      ruleObj = SailPointFactory.getCurrentContext().getObject(Rule.class, "Rule_Script_PowerShell_LogRotation");  
      String ruleSrc = ruleObj.getSource(); 
      ruleObj.setSource(ruleSrc);           
    }
    dataMap.put("postScript",ruleObj);      
    logger.error("Rule_Log_Rotation: dataMap "+dataMap);
    RpcResponse iqserviceResponse = callIQService(dataMap,"ScriptExecutor",iqServiceHost,iqServicePort);  
    logger.error("Rule_Log_Rotation: executeCmdLet: iqserviceResponse : "+iqserviceResponse.toXml());
    return iqserviceResponse;  
  } 
  
  public RpcResponse callIQService(Map data, String rpcService,String iqServiceHost, int iqServicePort) throws Exception{ 
	logger.error("Prinnt 3");  
    RPCService service = new RPCService(iqServiceHost, iqServicePort);
    logger.error("Rule_Log_Rotation: data "+data);				
    RpcRequest request = new RpcRequest(rpcService, "runAfterScript" , data);
    RpcResponse response = service.execute(request);
    return response;  
  }
  
  
  String finalOutputResponse = null;
  try {      
	String TFAYD_IQSERVICE_HOST = "ushapws00278la.stg-tfayd.com";
    int TFAYD_IQSERVICE_PORT = 5050;			
    finalOutputResponse =  rotateLog(TFAYD_IQSERVICE_HOST,TFAYD_IQSERVICE_PORT);
  } catch(Exception e) {
    finalOutputResponse = e.getMessage();
  }

  return finalOutputResponse;
  
  ]]></Source>
</Rule>

While running the rule, I see below error:

Backgrounding step Initialize
2024-04-19T13:01:03,665 ERROR QuartzScheduler_Worker-4 Rule_Log_Rotation:166 - Start of Rule_Log_Rotation
2024-04-19T13:01:03,665 ERROR QuartzScheduler_Worker-4 Rule_Log_Rotation:166 - Prinnt 1
2024-04-19T13:01:03,665 ERROR QuartzScheduler_Worker-4 Rule_Log_Rotation:166 - Prinnt 2
2024-04-19T13:01:03,665 ERROR QuartzScheduler_Worker-4 Rule_Log_Rotation:166 - Rule_Log_Rotation: Entry into IF loop : if Rule name is Rule_Script_PowerShell_LogRotation
2024-04-19T13:01:03,668 ERROR QuartzScheduler_Worker-4 Rule_Log_Rotation:166 - Rule_Log_Rotation: dataMap {postScript=sailpoint.object.Rule@7e36b337[id=6466b2818ef11ad0818ef5e991f437c7,name=Rule_Script_PowerShell_LogRotation]}
2024-04-19T13:01:03,668 ERROR QuartzScheduler_Worker-4 Rule_Log_Rotation:166 - Prinnt 3
2024-04-19T13:01:03,668 ERROR QuartzScheduler_Worker-4 Rule_Log_Rotation:166 - Rule_Log_Rotation: data {postScript=sailpoint.object.Rule@7e36b337[id=6466b2818ef11ad0818ef5e991f437c7,name=Rule_Script_PowerShell_LogRotation]}
2024-04-19T13:01:03,678 ERROR QuartzScheduler_Worker-4 Rule_Log_Rotation:166 - Error Response in CatchErrors returned from IQService. Value cannot be null.
Parameter name: s
2024-04-19T13:01:03,678 ERROR QuartzScheduler_Worker-4 Rule_Log_Rotation:166 - End of Rule_Log_Rotation
2024-04-19T13:01:03,678 ERROR QuartzScheduler_Worker-4 Rule_Log_Rotation:166 - Rule_Log_Rotation_updated: outputResponse : Errors returned from IQService. Value cannot be null.
Parameter name: s

@avikrsingh23
As your IQService log file is constant, I suggest you to have PowerShell script in your IQService Server directly and schedule this script to run at regular intervals using Windows Task Scheduler.
Actually this would be easy method to do this.

Coming to your error, if you want to go with this same process , please try below and let me know

Please modify the lines as below in your code in callIQService method and try

RpcRequest request = new RpcRequest(“ScriptExecutor”, “runAfterScript”, data);
RpcResponse response = service.execute(request);

Hi @avikrsingh23

Welcome :).

May I ask why you need to change the IQService logs through rule or PS? could you please shed more light on the use-case itself if you don’t mind for sure?

The requirement is to rename the log once its size is above 500PM. For this create/schedule a weekly Task which will execute a rule. This rule will execute another rule which actually contains a powershell script. this script will check the size of the log, if more than 500MB then rename with date time append.
Rule is Rule_NBCU_Log_Rotation
Rule script is Rule_NBCU_Script_PowerShell_LogRotation.

The powershell script is correct and tested.
I am having doubt that there is some mistake in data map creation and RPC execution,
Both the files are attached above.

1 Like

Still same error comming

Hi @avikrsingh23

I’m not sure that I’m understanding correctly…​ But you can go to the path HKEY_LOCAL_MACHINE\SOFTWARE\SailPoint\IQService on the IQService installed server and change the below keys:

-maxTraceFiles: maximum number of Trace log files that must get created before overwriting the older files.

-traceFileSize: maximum file size of a trace file in bytes

A new file is created when the current file exceeds this limit.

Restart the IQService service.

Then you can write the simple script to change the file concatenating with a number, not the original one.

As has been mentioned, I would use the built-in log-rolling feature. Set the size of the file, number of files, and ALSO, make sure your log level is not set too low as you may be logging too much and filling up your logs. We have a lot of activity in IQService, but our logs do not fill up that fast.

Also, if you ingest your logs into a log aggregator (e.g., Splunk), you won’t need to keep your log files on the server any more and you can just have them auto-delete.