• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

Coldfusion Log JSON Format

Explorer ,
Jun 30, 2022 Jun 30, 2022

Copy link to clipboard

Copied

I need all my Coldfusion logs to store in JSON format.

I can then parse those logs as a single line rather than a multi-line.

How can I achieve that?

 

Thanks,
Souvik

Views

183

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jun 30, 2022 Jun 30, 2022

Copy link to clipboard

Copied

To be clear, there's no cf feature to enable that. You should be able to find generic 3rd party tools offering to convert a text log file to json.

 

You may even be able to find some tomcat-specific feature or add-on providing for this.

 

Either way (and to your last point), do note that there are 2 kinds of cf logs: those that are single-line (most of them), having a date/time at the start of each line. Then there are a few that are multi-line (having lines without a datetime), including the coldfusion-out.log, coldfusion-error.log, and exception.log, though SOMETIMES they are single-line, depending on the circumstance.

 

If the latter may be what you refer to, I suspect you'll have a heck of a time converting those to single-line, though I suppose with some tools it may be possible.

 

Let us know if you find anything, or perhaps someone else will have an idea for you. 


/Charlie (troubleshooter, carehart.org)

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jul 02, 2022 Jul 02, 2022

Copy link to clipboard

Copied

Even if ColdFusion had the facility to do that, why would you bother at all? Just let ColdFusion do its thing. You do yours. 🙂

 

Converting a ColdFusion log file to JSON format is straightforward. Take the gateway log file, for example:

 

<cfset logFileAsIs=fileread("C:\ColdFusion2021\cfusion\logs\eventgateway.log")>

<cfset logFileAsArray=[]>

<!--- Using line-break as delimiter, convert each line of log
into an element in an array --->
<cfloop list="#logFileAsIs#" delimiters="#chr(10)&chr(13)#" index="line">
	<cfset arrayAppend(logFileAsArray, "{#line#}")>
</cfloop>

<cfset logFileAsJSON=serializeJSON(logFileAsArray)>

<!---<cfdump var="#logFileAsArray#" label="logFileAsArray">--->
<!---<cfdump var="#logFileAsJSON#" label="logFileAsJSON">--->

 

 

 

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Jul 04, 2022 Jul 04, 2022

Copy link to clipboard

Copied

@BKBK Thank you for the reply.

I think your solution will only work for single-line log files, not for multi-line log files.

I need to parse multi-line log files also.

Let me know your thoughts.

 

Thanks,
Souvik

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jul 04, 2022 Jul 04, 2022

Copy link to clipboard

Copied

Sorry, I don't understand what you mean by "single-line" and "multi-line".

Could you please provide examples to illustrate.

Thanks.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jul 04, 2022 Jul 04, 2022

Copy link to clipboard

Copied

Alfred, I know you're asking Souvik, but I did already address this earlier here : "do note that there are 2 kinds of cf logs: those that are single-line (most of them), having a date/time at the start of each line. Then there are a few that are multi-line (having lines without a datetime), including the coldfusion-out.log, coldfusion-error.log, and exception.log, though SOMETIMES they are single-line, depending on the circumstance."


/Charlie (troubleshooter, carehart.org)

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jul 11, 2022 Jul 11, 2022

Copy link to clipboard

Copied

LATEST
 

I think your solution will only work for single-line log files, not for multi-line log files.

I need to parse multi-line log files also.

Let me know your thoughts.

 

By @Souvik Saha Choudhury

 

Hi @Souvik Saha Choudhury ,

 

The following code will covert the usual ColdFusion files (in /cfusion/logs/) to JSON. It takes into account that multiple lines of log may occur under a given date-time.

 

I should like to hear if it helped.

 

<!--- 
Convert the usual log files in \cfusion\logs to JSON format.
The JSON consists of key-value pairs, the keys being the line numbers.
--->

<cfdump var="#convertLogFileToJSON('C:\ColdFusion2021\cfusion\logs\application.log')#">

<!---
<cfdump var="#convertLogFileToJSON('C:\ColdFusion2021\cfusion\logs\coldfusion-error.log')#">
<cfdump var="#convertLogFileToJSON('C:\ColdFusion2021\cfusion\logs\exception.log')#">
<cfdump var="#convertLogFileToJSON('C:\ColdFusion2021\cfusion\logs\eventgateway.log')#">
<cfdump var="#convertLogFileToJSON('C:\ColdFusion2021\cfusion\logs\server.log')#">
--->


<cffunction name="convertLogFileToJSON" returnformat="JSON"  output="false">
	<cfargument name="logFilePath" type="string" required="yes">
	
	<cfset var logFileContentAsIs=fileread(arguments.logFilePath)>
	<cfset var filename=lCase(listFirst(listLast(arguments.logFilePath,"/\"),"."))>
	
	<cfset var logFileContentAsArray=[]>
	<cfset var lineTriggersArrayEntry=false>
	<cfset var index=1>
	<cfset var logCategory=0>
	
	<cfset var tempStruct={}>
	
	<cfswitch expression="#filename#" >		
		<!--- 
		Case: CF log file in which the first line characters up to and including ' AM ' or ' PM ' 
		form a date-time.  
		For example, coldfusion-error,coldfusion-out
		--->
		<cfcase value="coldfusion-error,coldfusion-out"  delimiters=",">
			<cfset logCategory=1>
		</cfcase>
		
		<!--- 
		Default Case: CF log file in which the 3rd and 4th comma-delimited columns form a date-time.
		For example, application,audit,cfpm-audit,eventgateway,exception,http,mail,monitor,restservice,scheduler,
		server,webservice
		 --->
		<cfdefaultcase>
			<cfset logCategory=2>
		</cfdefaultcase>
	</cfswitch>
		
	
	<!--- 
	1. Use line-break as delimiter to pick out each line of log.
	2. Each log entry is determined by a date-time. So group as one 
	   entry all the lines of log that occur on the same date, 
	   and store them as one element in an array. 
	--->
		
	<cfloop list="#logFileContentAsIs#" delimiters="#chr(10)&chr(13)#" index="line">
					
		<cfset lineTriggersArrayEntry=triggerArrayEntry(logCategory, line)>
		
		<!---Start by handlng the first line of log, which is usually the header.--->
		<cfif index eq 1>
			<cfset logFileContentAsArray[index]={"line1":"#line#"}>
		</cfif>
		
		<cfif lineTriggersArrayEntry>
			<cfset index=index+1>
			<cfset logFileContentAsArray[index]={"line#index#":"#line#"}>
		<cfelse>
			<cfset var tempStruct=duplicate(logFileContentAsArray[index])>
			<cfset structUpdate(tempStruct,"line#index#",tempStruct["line#index#"] & chr(13) & chr(10) & line)>
			<cfset logFileContentAsArray[index]=tempStruct>
		</cfif>
				
	</cfloop>
	
	<cfset var logFileContentAsJSON=serializeJSON(logFileContentAsArray)>
	
	<cfreturn logFileContentAsJSON>
 </cffunction>
 
 <!--- 
 Given a line of log of a particular category,
 this function extracts a substring from line 
 at a location where we would expect a date.
 
 True is returned if the extracted substring is a valid date.
 False is returned otherwise
  --->
<cffunction name="triggerArrayEntry" returntype="boolean">
	<cfargument name="logCategory" type="numeric" required="yes">
	<cfargument name="line" type="string" required="yes">
	
	<cfset var arrayEntryTrigger=false>
	<cfset var testSubstringFromLine="">
	
	<cfif arguments.logCategory eq 1>
		<cfset arguments.line=trim(arguments.line)>
		<!--- 
		Assuming the first characters in the line, up to and including ' AM ' or ' PM ' 
		form a date-time. 
		(the 3 consists of the number of characters in ' AM' or ' PM')
		--->
		<cfset testSubstringFromLine=left(arguments.line, 3+reFindNoCase("^*.\sAM\s|^*.\sPM\s",line,1))>
	<cfelseif arguments.logCategory eq 2>
		<!--- Assuming line to be list with comma as delimiter, extract and merge 3rd and 4th elements --->
		<cfif listLen(arguments.line) gte 4>
			<cfset testSubstringFromLine=toString(replace(listGetAt(arguments.line,3) & " " & listGetAt(arguments.line,4), '"', '', "all"))>
		</cfif>		
	</cfif>
	
	<cfreturn isDate(testSubstringFromLine)>
	
</cffunction>

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Resources
Documentation