i was creating my own style of logging and i found a strange issue i do not understand, so apologies if this is in the wrong forum\channel
i originally did not have the top 2 lines, so i added these during dev
( FolderMain =
FolderSub =
)
in the Console i can see what the print functions are returning, which is where my ? begins. if i have a temporary variable FolderMain and i set the content to be "Cloudy" at the beginning of each time it called how is it not "Cloudy" ?
i will say while developing i know i mistakenly wrote "Cloudy with meatballs" to the container, but it is not disposing of the variables after use (Wheres my trash collector) therefore causing some cod issues upon re-use.
What have i missed here?
best and thanks
Alan
P.S. Im sure there is something already built for this but being new to python / java its a great exercise for me dredge thru "so far"
Full Source code below:
def funcLog(vStatus, vFunction, vString):
# Function Number: 04
# Description:
# Return a Log according to the Log Condition
# Parameters:
# vStatus --> Message Status:
# Negative < 0 - Error Message
# Positive >= 0 - Warning / Information
# vString --> Message to be written
# vFunction --> Function that sent the message
# Created by Alan Cannon 09/30/06
# 17 March 2023 -Imported and Modified for Ignition by Alan Cannon
# Source Document contents
# f = open(TRACELOG_NAME, "a")
# f.write(vstrMessageTemp)
# f.close()
# External Variables:
import os, stat
import shutil
#from os import Path
FolderMain = []
FolderSub = []
# Variable Dclaration
vintCharLimit = 250 # Limit in Bytes
vstrMessageTemp = ""
vFileExtention = ".txt"
FilePrefixName = "App_Tracelog"
FolderMain = "C:\HMILOGS\"
FolderSub = "C:\HMILOGS\BACKUPS"
# Get the logDateFormat from the File based on a Fixed location format in the file name
strYear = str(system.date.getYear(system.date.now()))
strMonth = str((system.date.getMonth(system.date.now()))+1)
strDay = str(system.date.getDayOfMonth(system.date.now()))
strHour = str(system.date.getHour24(system.date.now()))
strMin = str(system.date.getMinute(system.date.now()))
strSec = str(system.date.getSecond(system.date.now()))
strMillis = str(system.date.getMillis(system.date.now()))
tempgTraceLogPath = system.tag.readBlocking("[default]gStn_100/gTraceLogFullPath")[0].value
tempgTraceLogName = system.tag.readBlocking("[default]gStn_100/gTraceLogName")[0].value
TRACELOG_SIZE = system.tag.readBlocking("[default]gStn_100/gTracelogSize")[0].value
print "Folder Main Start "+FolderMain
# check the Month, day hour for signle digit values
if len(strMonth) < 2:
strMonth = "0"+str(strMonth)
if len(strDay) < 2:
strDay = "0"+str(strDay)
if len(strHour) < 2:
strHour = "0"+str(strHour)
# Varify that The TraceLog File Data is Ready for Writing
if len(str(tempgTraceLogName)) == 4:
LogDateFormat ="_"+str(strMonth)+"_"+str(strDay)+"_"+str(strYear)
TRACELOG_NAME = FilePrefixName+str(LogDateFormat)+str(vFileExtention)
TraceLogFullFilePath = FolderMain +TRACELOG_NAME
system.tag.writeBlocking("[default]gStn_100/gTraceLogName",TRACELOG_NAME)
system.tag.writeBlocking("[default]gStn_100/gTraceLogFullPath",TraceLogFullFilePath)
vStatus= 1
vString = "System Startup on ["+str(system.date.now())+"]"
tempgTraceLogPath = TraceLogFullFilePath
# Verify if there are a Message Type as vStatus[]
if (vStatus < 0):
# Write the Error Message
vstrMessageTemp = "Error Message: " +str(vFunction) + ". Status: (" +str(vStatus) + ") - " +str(vString) & "Time:" +str(system.date.now())+"\n"
if (vStatus == 1):
# Write the information Message
vstrMessageTemp = "Information Message: " +str(vFunction) + ". Status: (" +str(vStatus) + ") - " +str(vString) + " Time:" +str(system.date.now())+"\n"
if (vStatus == 2):
# Write the Warning Message
vstrMessageTemp = "Warning Message: " +str(vFunction) + ". Status: (" +str(vStatus) + ") - " +str(vString) + " Time:" +str(system.date.now())+"\n"
if (vStatus == 3):
# Write the Database Message
vstrMessageTemp = "Database Message: " +str(vFunction) + ". Status: (" +str(vStatus) + ") - " +str(vString) + " Time:" +str(system.date.now())+"\n"
if (vStatus == 4):
# Write the Cycletime Message
vstrMessageTemp = "Cycletime Message: " +str(vFunction) + ". Status: (" +str(vStatus) + ") - " +str(vString) + " Time:" +str(system.date.now())+"\n"
else:
# Write the General Message
vstrMessageTemp = "General Message: " +str(vFunction) + ". Status: (" +str(vStatus) + ") - " +str(vString) + " Time:" +str(system.date.now())+"\n"
# ************************************************************************************
# Trace Log File Size Determination if > that Value in The Structure it will Auto Delete the File and On Next Execution of this function
# it will recreate the Log .TXT File
# Write to the file
tracelogFile = open(tempgTraceLogPath, "a")
tracelogFile.write(vstrMessageTemp)
tracelogFile.close()
print "Folder Main after writing "+FolderMain
# Read the Size of the file
statinfo = os.stat(tempgTraceLogPath)
LOGFILE_SIZE = (statinfo.st_size/1000)
string= tempgTraceLogName
filename=string[:-4]
vFileYear = filename[-4:]
filePrefix=filename[-10:]
vFileMonth = filePrefix[0:2]
vFileDay = filePrefix[3:-5]
# if the size is greater than expected create a new one
if (LOGFILE_SIZE > TRACELOG_SIZE):
LogDateFormat ="_"+str(vFileMonth)+"_"+str(vFileDay)+"_"+str(vFileYear)
TRACELOG_NAME = FilePrefixName+LogDateFormat+vFileExtention
vFileRename = filename
vFileRename =vFileRename+"_"+str(str(strMin)+str(strSec))+vFileExtention
shutil.move(tempgTraceLogPath, FolderSub+"\\"+tempgTraceLogName)
os.rename(FolderSub+"\\"+tempgTraceLogName, FolderSub+"\\"+vFileRename)
# Create a New file since we just moved and renamed the last one
vstrMessageTemp = "General Message: " +str("New File Created in Process") + ". Status: (" +str(99) + ") - " +str("file Size Exceeded Creating a New File for This Day") + " Time:" +str(system.date.now())+"\n"
LogDateFormat ="_"+str(strMonth)+"_"+str(strDay)+"_"+str(strYear)
TRACELOG_NAME = FilePrefixName+str(LogDateFormat)+str(vFileExtention)
#print "Folder Main "+FolderMain
#print "TraceLog Name "+TRACELOG_NAME
# Forcing the values since i dont understand why FolderMain is not = to "C:\HMILOGS\"
newFileLogPath = "C:\\HMILOGS\\"+TRACELOG_NAME
print newFileLogPath
tracelogFile = open(newFileLogPath, "a")
tracelogFile.write(vstrMessageTemp)
tracelogFile.close()
# Check The Date of the Log File and Create a New One if Needed
if ((strMonth <> vFileMonth) or (strDay <> vFileDay) or (strYear <> vFileYear)):
LogDateFormat ="_"+str(strMonth)+"_"+str(strDay)+"_"+str(strYear)
TRACELOG_NAME = FilePrefixName+LogDateFormat+vFileExtention
TraceLogFullFilePath = TraceLogPath+TRACELOG_NAME
system.tag.writeBlocking("[default]gStn_100/gTraceLogName",TraceLogFullFilePath)
# *************************************************************************************************************
Use the </> button to format your code. Select the code and press the button. Check the preview before submitting.
2 Likes
As long as it's just an exercise because I would not recommend building your own logger for production.
However, after you format the code, what exactly is the issue/question? I'm not sure I understand the issue, what line of code is giving you something unexpected?
Also since this is for learning I would recommend against the following

Imaging you are logging something right on the edge of midnight - you could have the day be yesterday and then the hour become 0 (for midnight the next day) which would make your log look like it occured the midnight prior. Or really just on the edge of any hour this could make things look like it occured an hour earlier than it did.
Call system.date.now()
once in the beginning and then parse it.
2 Likes
my question is related to the following
FolderMain = "Some Value"
When im using the console window to perform the actions i added the print statement to see why my file names were funky and i found that at the begining when i set the Foldermain to the path i wanted the console or editor was not re-writing it to what i intended at the beginning of the function execution. it was retaining some other value that i am not setting
FolderMain = "C:\HMILOGS"
When i use the print FolderMain it returns "C:\HmiLogs\Backups".. It cant be anything other than my declaration....
Transistor: I am not following </> when i submit Don't submit actual code but commented code?
- Hit the 🖉 edit button below your post.
- Select a block of Python code.
- Press the </> button on the editor toolbar. It's a formatting button so it works the same as the B or I buttons. It will preserve indentation and syntax highlighting.
- Repeat for each block of code.
There is something similar on almost every forum using Markdown text entry.
1 Like
You're declaring FolderMain twice; once as an empty list and once as C:\HMILOGS\"
.
You are never redeclaring or reassigning FolderMain after that point. I don't see what's unexpected.
This is your code, properly formatted.
Click the icon at the top of the forum's text box that looks like </> and paste your code in between the three characters it enters:
```
your code
```
def funcLog(vStatus, vFunction, vString):
# Function Number: 04
# Description:
# Return a Log according to the Log Condition
# Parameters:
# vStatus --> Message Status:
# Negative < 0 - Error Message
# Positive >= 0 - Warning / Information
# vString --> Message to be written
# vFunction --> Function that sent the message
# Created by Alan Cannon 09/30/06
# 17 March 2023 -Imported and Modified for Ignition by Alan Cannon
# Source Document contents
# f = open(TRACELOG_NAME, "a")
# f.write(vstrMessageTemp)
# f.close()
# External Variables:
import os, stat
import shutil
#from os import Path
FolderMain = []
FolderSub = []
# Variable Dclaration
vintCharLimit = 250 # Limit in Bytes
vstrMessageTemp = ""
vFileExtention = ".txt"
FilePrefixName = "App_Tracelog"
FolderMain = "C:\HMILOGS\"
FolderSub = "C:\HMILOGS\BACKUPS"
# Get the logDateFormat from the File based on a Fixed location format in the file name
strYear = str(system.date.getYear(system.date.now()))
strMonth = str((system.date.getMonth(system.date.now()))+1)
strDay = str(system.date.getDayOfMonth(system.date.now()))
strHour = str(system.date.getHour24(system.date.now()))
strMin = str(system.date.getMinute(system.date.now()))
strSec = str(system.date.getSecond(system.date.now()))
strMillis = str(system.date.getMillis(system.date.now()))
tempgTraceLogPath = system.tag.readBlocking("[default]gStn_100/gTraceLogFullPath")[0].value
tempgTraceLogName = system.tag.readBlocking("[default]gStn_100/gTraceLogName")[0].value
TRACELOG_SIZE = system.tag.readBlocking("[default]gStn_100/gTracelogSize")[0].value
print "Folder Main Start "+FolderMain
# check the Month, day hour for signle digit values
if len(strMonth) < 2:
strMonth = "0"+str(strMonth)
if len(strDay) < 2:
strDay = "0"+str(strDay)
if len(strHour) < 2:
strHour = "0"+str(strHour)
# Varify that The TraceLog File Data is Ready for Writing
if len(str(tempgTraceLogName)) == 4:
LogDateFormat ="_"+str(strMonth)+"_"+str(strDay)+"_"+str(strYear)
TRACELOG_NAME = FilePrefixName+str(LogDateFormat)+str(vFileExtention)
TraceLogFullFilePath = FolderMain +TRACELOG_NAME
system.tag.writeBlocking("[default]gStn_100/gTraceLogName",TRACELOG_NAME)
system.tag.writeBlocking("[default]gStn_100/gTraceLogFullPath",TraceLogFullFilePath)
vStatus= 1
vString = "System Startup on ["+str(system.date.now())+"]"
tempgTraceLogPath = TraceLogFullFilePath
# Verify if there are a Message Type as vStatus[]
if (vStatus < 0):
# Write the Error Message
vstrMessageTemp = "Error Message: " +str(vFunction) + ". Status: (" +str(vStatus) + ") - " +str(vString) & "Time:" +str(system.date.now())+"\n"
if (vStatus == 1):
# Write the information Message
vstrMessageTemp = "Information Message: " +str(vFunction) + ". Status: (" +str(vStatus) + ") - " +str(vString) + " Time:" +str(system.date.now())+"\n"
if (vStatus == 2):
# Write the Warning Message
vstrMessageTemp = "Warning Message: " +str(vFunction) + ". Status: (" +str(vStatus) + ") - " +str(vString) + " Time:" +str(system.date.now())+"\n"
if (vStatus == 3):
# Write the Database Message
vstrMessageTemp = "Database Message: " +str(vFunction) + ". Status: (" +str(vStatus) + ") - " +str(vString) + " Time:" +str(system.date.now())+"\n"
if (vStatus == 4):
# Write the Cycletime Message
vstrMessageTemp = "Cycletime Message: " +str(vFunction) + ". Status: (" +str(vStatus) + ") - " +str(vString) + " Time:" +str(system.date.now())+"\n"
else:
# Write the General Message
vstrMessageTemp = "General Message: " +str(vFunction) + ". Status: (" +str(vStatus) + ") - " +str(vString) + " Time:" +str(system.date.now())+"\n"
# ************************************************************************************
# Trace Log File Size Determination if > that Value in The Structure it will Auto Delete the File and On Next Execution of this function
# it will recreate the Log .TXT File
# Write to the file
tracelogFile = open(tempgTraceLogPath, "a")
tracelogFile.write(vstrMessageTemp)
tracelogFile.close()
print "Folder Main after writing "+FolderMain
# Read the Size of the file
statinfo = os.stat(tempgTraceLogPath)
LOGFILE_SIZE = (statinfo.st_size/1000)
string= tempgTraceLogName
filename=string[:-4]
vFileYear = filename[-4:]
filePrefix=filename[-10:]
vFileMonth = filePrefix[0:2]
vFileDay = filePrefix[3:-5]
# if the size is greater than expected create a new one
if (LOGFILE_SIZE > TRACELOG_SIZE):
LogDateFormat ="_"+str(vFileMonth)+"_"+str(vFileDay)+"_"+str(vFileYear)
TRACELOG_NAME = FilePrefixName+LogDateFormat+vFileExtention
vFileRename = filename
vFileRename =vFileRename+"_"+str(str(strMin)+str(strSec))+vFileExtention
shutil.move(tempgTraceLogPath, FolderSub+"\\"+tempgTraceLogName)
os.rename(FolderSub+"\\"+tempgTraceLogName, FolderSub+"\\"+vFileRename)
# Create a New file since we just moved and renamed the last one
vstrMessageTemp = "General Message: " +str("New File Created in Process") + ". Status: (" +str(99) + ") - " +str("file Size Exceeded Creating a New File for This Day") + " Time:" +str(system.date.now())+"\n"
LogDateFormat ="_"+str(strMonth)+"_"+str(strDay)+"_"+str(strYear)
TRACELOG_NAME = FilePrefixName+str(LogDateFormat)+str(vFileExtention)
#print "Folder Main "+FolderMain
#print "TraceLog Name "+TRACELOG_NAME
# Forcing the values since i dont understand why FolderMain is not = to "C:\HMILOGS\"
newFileLogPath = "C:\\HMILOGS\\"+TRACELOG_NAME
print newFileLogPath
tracelogFile = open(newFileLogPath, "a")
tracelogFile.write(vstrMessageTemp)
tracelogFile.close()
# Check The Date of the Log File and Create a New One if Needed
if ((strMonth <> vFileMonth) or (strDay <> vFileDay) or (strYear <> vFileYear)):
LogDateFormat ="_"+str(strMonth)+"_"+str(strDay)+"_"+str(strYear)
TRACELOG_NAME = FilePrefixName+LogDateFormat+vFileExtention
TraceLogFullFilePath = TraceLogPath+TRACELOG_NAME
system.tag.writeBlocking("[default]gStn_100/gTraceLogName",TraceLogFullFilePath)
The unexpected part I think is line 338 in his picture it prints Folder Main Start C:\HMILOGS\BACKUPS
but C:\HMILOGS
would be expected.
1 Like

I can't get an SSCCE to do anything unexpected. Showing the rest of the code in the utils
file might help. Even if I do something funky with globals
, I can't get the same behavior. I'll invite anyone to prove me wrong 
1 Like
@Alan_Cannon
What happens if you close designer, open it up, and first thing in script console run utils.funcLog(1, "Copy Test", "test 1")
, is it still wrong then?
same same
Designer closed and reopened
going to restart my VM now brb
ok i found the issue, but dont understand
i tried "\"
the r""
the str() which fixed it.
it was like the code was skipping the line completely.. thoughts????
In python, the backslash is an escape character. Consider using forward slases instead.
Copying into Notepad++ clarifies your issue. The last backslash escapes tail doublequote. The string would otherwise be grey.

1 Like
The forum's highlighting plugin even gets confused:

1 Like
btw guys.. Thank you for the support. very much appreciated
Cannon Controls
Alan Cannon