Log information in the grid

Hi All,

I have a use case where I need to show some of the log files such as audit/news_usage.csv and login-audit.csv in the grid. For the news usage grid,I have a grid columns such as Username, Action, Timestamp. And I have used readcsvlog() function and it is returning the csv contents. I am worried how to retrieve the contents from this log file and show up in the gird.

Please let me know how to achieve this.

Thanks in advance!

OriginalPostID-232737

  Discussion posts and replies are publicly visible

  • You will need to convert the CsvContents to a datasubset. todatasubset() and a!datasubset() may help you. The datasubset can then be used in the paging grid. Note that you will have to write your logic to convert the CsvContents in a appropriate format(an array), so that you can then pass it to the a!datasubset() or todatasubset() functions.
  • Also would suggest using the function readcsvlogpaging() instead of readcsvlog(). The reason is that this function allows you to control how many rows are returned from the log file, and you can also specify the sorting order.
  • 0
    Certified Senior Developer
    Be careful while using readlogcsv for login audit file. The default configuration for read log csv is to consider first row of csv file as header, but the login audit does not have any header. Now you will have to take special care for that. On the otherhand some log files does have proper headers.
  • Thanks Chetany for the inputs. I have gone through this sail recipes forum.appian.com/.../SAIL_Recipes.html
    Before loading the datas in todatasubset() ,the log data's should be like this
    { Username: "John Smith", Action: "Comment From Process", Timestamp:"xxx"},
    { Username: "Michael Johnson", Action: "Comment From Process" ,Timestamp:"xxx"},
    { Username: "Mary Reed", Action: "Event From Process", Timestamp:"xxx"}
    But the log data's were in the below format
    [logName=E:\\appian162\\logs\\audit\
    ews_usage.csv, totalCount=xx, rows=2 Jul 2016 15:42:24 GMT,_h-0000dcc8-996e-8000-0313-010000010000_128,Comment From Process; 31 Jul 2016 15:42:28 GMT,_h-0000dcc8-996e-8000-0313-010000010000_128,Comment From Process]

    Anyone help me how to format the data.
  • 0
    Certified Senior Developer
    Create a dummy display cdt and then split each element by commas (,) and set each element of a row to a column in dummy cst in a rule and use apply over this rule. Now use this cdt to create the grid.
  • @ashman Hi, you may choose any one of the following approaches to read, format and display the data:

    Approach - 1:

    Create a formatted CDT which contains the fields that can hold data from news_usage.csv and here is how you should do it:

    Step - 1: Create a CDT as follows:

    type!newsUsageLogCDT(
    \ttimestamp_ts:
    \tuser:
    \taction_txt:
    )

    Step - 2: Now create an expression which will populate the formatted cdt with the data from news_usage.csv and additionally you need to format the data read from news_usage.csv prior to assigning it to formatted cdt created above.

    fn!load(
    local!pagingInfo: a!pagingInfo(startIndex: 1, batchSize: 10,sort:a!sort(field:"timestamp_ts",ascending:false)),
    \tlocal!newsUsageCsvData: fn!readcsvlogpaging(
    \t csvPath: "audi
    ews_usage.csv",
    \t startIndex: 1,
    \t batchSize: -1
    \t),
    \t
    \tlocal!listOfUser_txt: fn!getdistinctusers(cons!GROUP_CONTAINING_ALL_USERS),
    \tlocal!listOfUuid_text: fn!apply(
    fn!user(
    _,
    "uuid"
    ),
    local!listOfUser_txt
    ),
    /*Just to let you know, uuid is a hidden attribute of User object and above two variables are intended for obtaining the user name by uuid. For more information, refer the rule at /search?q=OriginalPostID-203272 written by @mschmitt and you may use it directly.*/
    \t
    local!listOfNewsUsageCsvCdt:fn!apply(
    \t/*Refer to Step - 3 for implementation of rule!populateNewsUsageLogCDT() */
    \trule!populateNewsUsageLogCDT(
    \ trow: _,
    \ tlistOfUser_txt: local!listOfUser_txt,
    \ tlistOfUuid_text: local!listOfUuid_text
    \ t),
    \ tlocal!newsUsageCsvData.rows
    ),
    local!datasubset: a!dataSubset(
    startIndex: local!pagingInfo.startIndex,
    batchSize: local!pagingInfo.batchSize,
    totalCount: fn!length(local!listOfNewsUsageCsvCdt),
    data: local!listOfNewsUsageCsvCdt
    ),
    local!datasubset
    /*Now the datasubset is ready and you can use it anywhere.*/
    )

    Step - 3: A rule that actually reads each row (of news_usage.csv) and assigns the formatted values finally to type!newsUsageLogCDT, one at a time.

    Inputs:
    1. row (Text)
    2. listOfUser_txt(Text Multiple)
    3. listOfUuid_text (Text Multiple)

    Expression:

    fn!with(
    local!splitCells: fn!split(ri!row,","),
    \t/*Data will be in the text format, so we need to split it.*/
    \ttype!newsUsageLogCDT(
    \ ttimestamp_ts: local!splitCells[1],
    \ t/*Apply a date time conversion function above if you really want the data in timestamp format*/
    \ tuser: fn!index(ri!listOfUser_txt, fn!wherecontains(local!splitCells[2], ri!listOfUuid_text))
    \ taction_txt: local!splitCells[3]
    \t)
    )

    Pros:
    1. You can format the data.(Obviously no one wants to see uuid of a user and in fact it isn't recognisable by designer as well)
    2. As you are assigning the data to the fields in CDT, sorting is possible.
    Cons:
    1. You need to write your own code as mentioned above.

    Approach - 2:

    Have a look at rule!LR_displayCsv() and create a new version of it by removing the unwanted elements (such as filters, details etc).

    Pros:
    1. You may have most of the code in hand and you don't need to invest much time if you just want to replicate the grid.
    Cons:
    1. Sorting isn't possible.
    2. Formatting is possible if and only if you customise the grid in rule!LR_displayCsv() and in this case, it's more or less equal to Approach - 1 excluding few steps.
  • @ashman If you want the username to appear in a formatted manner, add an other column to CDT which holds the formatted name of the User object. This helps you in sorting the data. If sorting isn't required, you can obtain the formatted user name on the fly by applying the user() function on the User value present in the each record.
  • Thank you everyone for your valuable comments.
    @sikhivahans I tried your first approach and data's are formatted as expected.