Splunk Search
Highlighted

Format Command: Field Order

Communicator

Does anyone know a way to control the field order for the format command?

For the default use case of format it AND's columns and OR rows (simplified, but effectively) and the field order doesn't matter, but the format command gives us the ability to manipulate the separators and some of those use cases require controlling the column order.

Imagine you have a list of users and systems they are allowed to log in on that looks like:

User: System
fred: workstation1
tom: workstation2, server1
susan: workstation3, server1, server2

If you have those in a a lookup, it would be nice to write a correlation search like:

| tstats count from datamodel=Authentication where [
  | inputlookup user_systems
  | rename user as Authentication.user system as Authentication.src
  | fields Authentication.user Authentication.src
  | format  "(" " ( " " AND NOT " " ) " " OR " ")"
]
by user src

and have that expand to:

| tstats count from datamodel=Authentication where 
  (user=fred AND NOT (Authentication.src=workstation1))  OR
  (user=tom AND NOT (Authentication.src=workstation2 OR Authentication.src=server1) ) OR
  (user=susan AND NOT (Authentication.src=workstation3 OR Authentication.src=server1 OR Authentication.src=server2))
  by user src

NOTE: my actual correlation search would be slight more complicated as I really only want alerted once per user, but I'd like to preserver the count by system to give the soc analyst better visibility. I'm just simplifying here for the sake of the question.

The problem is this search is currently expanding with src first:

| tstats count from datamodel=Authentication where 
  ((Authentication.src=workstation1) AND NOT user=fred)  OR
  ((Authentication.src=workstation2 OR Authentication.src=server1)  AND NOT user=tom ) OR
  ((Authentication.src=workstation3 OR Authentication.src=server1 OR Authentication.src=server2) AND NOT user=susan)
  by user src

I've tried adding both fields and table to control the order of the fields, but neither appears to have an affect. Is there a way to control the order of the fields to format?

0 Karma
Highlighted

Re: Format Command: Field Order

Builder

If you replace the fields command on line 4 of your initial query to table, that should reorder the fields so they aren't alphabetically ordered, which is what appears to be happening. Let me know if that works.

If this comment/answer was helpful, please up vote it. Thank you.
0 Karma
Highlighted

Re: Format Command: Field Order

Communicator

As stated in my initial question: "I've tried adding both fields and table to control the order of the fields, but neither appears to have an affect", so at least in Splunk 6.6 table isn't the solution. I've re-verified that just in case I was wrong about testing.

NOTE: Edited in an attempt to make less harsh.

0 Karma
Highlighted

Re: Format Command: Field Order

Builder

Apologies for missing that statement. The answer you gave yourself covers any of the options that I can think of. The documentation does not appear to allow for ordering in the format command so your workaround 4 would be what I would have done.

If this comment/answer was helpful, please up vote it. Thank you.
0 Karma
Highlighted

Re: Format Command: Field Order

Communicator

Sorry if that come off harsh; you had no reason to apologize as you were just trying to help (and help at no cost to me). I was actually hoping some one would say it was fixed in a newer version.

I agree the 4 is probably the best although in this case 3 maybe the direction I go since it is a correlation search and it leads to a category in the identity lookup already. I think its easier to read which is important as we have a lot users at varying levels of Splunk expertise and I think there's value in being readable.

Hopefully some one will come up with a better solution; if there's not one today, maybe some time Splunk will say they've done an enhancement.

0 Karma
Highlighted

Re: Format Command: Field Order

Communicator

Since I hate searching and finding questions that don't have solutions, I thought I would provide the current known workarounds:

Workaround 1: List all users and just prefix sub-search with a NOT

| tstats count from datamodel=Authentication where NOT [
  | inputlookup user_systems
  | rename user as Authentication.user system as Authentication.src
  | fields Authentication.user Authentication.src
]
by user src

Workaround 2: Add a second sub-search to limit results to just monitored users

| tstats count from datamodel=Authentication where 
[
  | inputlooup user_systems
  | fields user
  | rename user as Authentication.user
]
NOT [
  | inputlookup user_systems
  | rename user as Authentication.user system as Authentication.src
  | fields Authentication.user Authentication.src
]
by user src

Workaround 3: Labeling monitored users (if using ES)

This is basically workaround 2, but is a slight optimization if you're using ES and are populating usercategory. If you're using ES you may be using the usersystems lookup to add a category to the user (e.g. monitored) and since ES will already be including the identity lookup to add user_category, you can leverage that.

| tstats count from datamodel=Authentication where Authentication.user_category = "Monitored" AND NOT [
  | inputlookup user_systems
  | rename user as Authentication.user system as Authentication.src
  | fields Authentication.user Authentication.src
]
by user src

Workaround 4: Don't use the format command. This is probably what you want, but its not the most readable solution

| tstats count from datamodel=Authentication where [
  | inputlookup user_systems
  | search system=* user=*
  | fields user system
  | eval search="( Authentication.user=" + user + " AND NOT ( Authentication.src=" + mvjoin(system, " OR Authentication.src=") + " )"
  | stats values(search) as search
  | eval search=mvjoin(search, " OR ")
]
by user src

You can make it slightly more readable by using printf:

| tstats count from datamodel=Authentication where [
  | inputlookup user_systems
  | search system=* user=*
  | fields user system
  | eval search=printf("Authentication.user=%s AND NOT ( Authentication.src=%s )", user, mvjoin(system, " OR Authentication.src="))
  | stats values(search) as search
  | eval search=mvjoin(search, " OR ")
]
0 Karma