10-11-2023 12:39 PM
I showed it at Wave and share it with all of you: when you use JSON to log, you can log anything, not just strings, you can log a Dictionary, a list, a MemberInfo, even a Databuffer.
First, you need to import JSON, add these 2 rows at the top of your rule:
Imports Newtonsoft.Json
Imports Newtonsoft.Json.Linq
Second, when you want to log, use JSON!
Dim stringobj As String = JsonConvert.SerializeObject(lCenterInfo,Formatting.Indented)
api.logmessage(lCenterInfo.Member.Name & ", lCenterInfo: " & stringobj)
When you use ,Formatting.Indented, your log will be correctly formatted.
Thanks to Matt Ha for enlightening me with JSON and @RobbSalzmann for sharing how to have the JSON string correctly formatted!
10-13-2023 02:07 PM
Hi Ludo,
Thanks for sharing these screenshots. I'm trying to get the JSON logging to work in our environment and was wondering if you could also share a full screenshot of the 2 public functions? The presentation files have some text running over them so that I can't see the full syntax for those. Thanks for any help.
10-25-2023 07:24 AM
Hi,
I just posted something on that topic:
[How to] Log into a file instead of the Error Log - OneStream Community (onestreamsoftware.com)
I hope it will help!
10-17-2023 04:12 PM
I think the conversion of the powerpoint to pdf may have stripped some of the images in the Wave documentation. Only the code for the WriteLogger Function is present. The AppendDBToLogger function seems to be missing. Could you share the code for it?
Thanks in advance!
10-25-2023 07:25 AM
Hi,
I posted something on the topic here:
[How to] Log into a file instead of the Error Log - OneStream Community (onestreamsoftware.com)
10-18-2023 01:48 AM
I think its probably worth mentioning that you can do all of this without JSON still (not saying there aren't reasons to use JSON) and perhaps in a more human-readable format.
For example, here is a bit of code outputting some datatable details. I don't think I wrote this bit of code I just had it saved in my code repository but I do this sort of thing all the time:
api.logmessage(
si,
"Datatable output",
String.Join(
vbnewline,
dtSimple.AsEnumerable.Select(Function(x) String.Concat(
"Source:",x.Item("Company code"),vbnewline,
"Target",":",x.Item("Fiscal year"),vbnewline,
"Product",":",x.Item("GL Account"),vbnewline
))))
I didn't get to go to your presentation @ludodepaz (due to everything being on at once!) but I wanted to and did go through the slides. I thought the coolest concept was where you were logging in memory and outputting to log/disk only when required.
.
10-18-2023 10:56 AM - edited 10-18-2023 11:01 AM
Thank you, I love it.
I combined it with the recommendations from the Advanced Solution Engineering Concepts session about the use of extensions.
With this addition:
Imports System.Runtime.CompilerServices
Imports Newtonsoft.Json
...
Public Module LogHelper
<Extension()>
Public Sub LogObject(ByVal errorLogApi As IBRApiErrorLog, ByVal si As SessionInfo, ByVal message As String, objectToLog As Object)
Try
Dim objAsJsonString As String = JsonConvert.SerializeObject(objectToLog, Formatting.indented)
brapi.ErrorLog.LogMessage(si, message, objAsJsonString)
Catch ex As Exception
Throw ErrorHandler.LogWrite(si, New XFException(si, ex))
End Try
End Sub
End Module
You can call the logging like this
brapi.ErrorLog.LogObject(si, "Log Object", someObject)
It works really nicely, cheers
10-18-2023 11:05 AM
That's very nice!
I need to find a good way to share the rules to log into a file and I get back to you.
10-18-2023 12:59 PM
Here is the image for the WriteLogger function from the pdf without the overlaying image, along with the code (or at least my best attempt to transcribe it, haha).
Public Shared Function WriteLogger (ByVal si As SessionInfo, ByVal api As Object, ByRef logger As System.Text.StringBuilder,
Optional ByVal fileName As String = "LOG", Optional ByVal folderName As String = "TestLogs",
Optional ByVal filesuffix As String = Nothing) As String
'Saves log to text file on application database
'
'Parameters
' logger: string builder object with contents of log file
' fileName: optional log file name. defaults to LOG
' folderName: optional log folder destination. defaults to TestLogs
' fileSuffix: optional log file suffix. defaults to system time
'Returns
' filepath of log file
If filesuffix Is Nothing Then
fileSuffix = DateTime.Now.ToString("yyyy-MM-dd_HHmmss")
End If
Dim logFileName As String = fileName & "_" & filesuffix & ".txt"
Dim targetFolder As String = folderName
Dim targetPath As String = "Documents/Public"
'Create folder if it does not exist
Dim folderPath As XFFolderEx = BRApi.FileSystem.GetFolder(si, FileSystemLocation.ApplicationDatabase, targetPath & "/" & targetFolder)
If folderPath Is Nothing Then
BRapi.FileSystem.CreateFullFolderPathIfNecessary(si, FileSystemLocation.ApplicationDatabase, targetPath, targetFolder)
End If
'Create File with logger contents and save in folder
Dim targetDir As String = BRApi.FileSystem.GetFolder(si, FileSystemLocation.ApplicationDatabase, targetPath & "/" & targetFolder).XFFolder.FullName
Dim dbFileInfo As New XFFileInfo(FileSystemLocation.ApplicationDatabase, logFileName, targetDir, XFFileType.Unknown)
dbFileInfo.ContentFileContainsData = True
dbFileInfo.ContentFileExtension = dbFileInfo.Extension
Dim dbFile As New XFFile(dbfileInfo, String.Empty, System.Text.Encoding.UTF8.GetBytes(logger.ToString))
BRApi.FileSystem.InsertOrUpdateFile(si, dbfile)
Return dbFile.FileInfo.FullName
End Function
12-08-2023 07:57 AM
Hi Ludo,
Many thanks for sharing the code for logging using Json - I tried but I am not getting any results. Here is my code:
12-08-2023 08:44 AM
Hi Wei,
the results look good to me. You only see 1 member at a time, you can log ctryList =and you will see the entire list if it's what you're looking for.
best
12-08-2023 09:03 AM
Thanks Ludo - I am getting "null" for LocalDescription for all of them, where your deck shows there should be some property information listed under "LocalDescription" - are there any other config I need to do to see them?
Thank you
Wei
12-08-2023 09:59 AM
Oh I see, the Local Description field is misleading. Only the Default Description is stored in the MemberInfo table
Descriptions in multiple languages are stored in another table, you can read it in a rule with a Dictionary(Of String, Memberdescription).
This is a good place to start: Solved: Cannot save Descriptions to a member - OneStream Community (onestreamsoftware.com)
12-08-2023 10:31 AM
Hi Ludo, I don't have access to the link you shared, are you able to provide more details on that? I will give Dictionary a try.
Thanks
Wei
12-08-2023 11:14 AM
12-08-2023 11:24 AM
Sorry Ludo - the same "Access Denied"!