Saturday, November 4, 2023

CQLing Game Data - The Blog Version

I've been learning CrowdStrike's LogScale platform recently. To help myself learn the CrowdStrike Query Language (CQL) I figured I'd do some analysis of game data I had collected awhile ago. Help me learn and then create this post to perhaps help others who might be learning CQL as well. 

That end, this post is a more written version of the live & somewhat interactive LogScale dashboard located: here

I'm providing the data itself at the bottom of this post if you want to monkey around with it.

It isn't uncommon for users of tools like LogScale to not know where to start from a query perspective. Something unique with LogScale is being able to easily share dashboards outside of the tool itself. This is a pretty cool capability! The other place where I see individuals somewhat struggle is how to create a dashboard. Not mechanically as much as how to lay out data. 

I should note the way I structured both my queries and the eventual dashboard should not be considered the 'right' way to do things. As with any language there are often multiple ways to achieve the same outcome. Start by making sure you are displaying the data you think you are displaying and then work toward efficiencies. As you gain experience that efficiency starts to be baked into your initial query creation.

A great CQL primer can be found: here

My original Splunk version of this post: here

Feel free to jump between the two posts to do a comparison of the query languages. That's fine as folks might have a Splunk frame of reference. I might even call out a few things here and there. What I'm not trying to do with this post is to say one tool is better than the other. 

Data Background - there used to be this great little mobile game called Darkfire Heroes. One of the game modes was a 1v1 PvP match. They once did a 2 day PvP event to see which clans would get the most wins. Outside of the event itself, each clan could 'fill' a weekly rewards chest through any PvP win. Participation in the event then is a 2fer! As a side note, clans could hold up to 50 people.  I should mention this data was manually collected and needed to be collected prior to the event's end. There are some gaps in terms of player names, all clan names, all clan participation, etc.

Analytic Goals - putting yourself in the shoes of a game admin or owner is not too much different that being a system admin (conceptually). In my case I'd want to do know things like

  • What does participation overall look like?
  • What clans are fully active and what does that drop off look like?
  • Was the event enough of a driver to have clans fill their clan rewards chest?
  • How full are clans?
  • And then fun things like looking at the top 10 and comparing activity to the rest of the game dataset. That last part is beyond what I have of course.

Let's begin!

Oh I should note since I didn't ingest this data and LogScale doesn't currently have a way to simply pull up an uploaded CSV, I created a search with the raw data, saved it, and then call up that search as a function [ ie save the query as dfh_clan efforts then start a separate query with $dfh_clan_efforts() ]. 

1. Total Clans Participating

createEvents(["236"])  
| select(@rawstring)

Creating events in LogScale feels a bit different to me than in Splunk. I'm not sure why TBH. I think because the entire event is captured in the command itself. In Splunk you use makeevent, add an eval for the strings, and then break the string up if you are creating multiple events. Either language, you probably wont be using the command much. Here I just need to call out there was 236 clans. Don't give me grief - I manually collected the data I do have! 

2. Total Matches Played

$dfh_clan_leaderboard()  
| sum(wins, as=wins)  
| games := wins * 2  
| drop([wins]) 

Since the game showed just wins I needed to swag how many games were actually played. I was pretty generous and applied an across the board 50% win average (note line 3). This isn't quite a fermi problem but for us it moves the needle. Ironically when I was reviewing my Splunk post I realized I posted the wrong output number in the screenshot. Whoops.

I'll call out the assignment operator ( := ) as an interesting bit with CQL. While there is an eval command, this can serve as a substitute or shorthand of that function. I found myself using it a lot.

3. Clan Chests Filled

$dfh_clan_leaderboard()  
| wins > 1000  
| count()  

It actually took 1,186 PvP wins to fill a clan rewards chest but I collected my data a few hours before it ended so gave people the benefit of the doubt. Folks will note that you can simply drop filter statements as you go. You can also use boolean logic in the filter statements though given the small dimensionality of my data I don't do that in any of my queries. For example Diable2 and SpawnsofDiablo were separate clans but were related as a 'clan family.' If I wanted to pull them up together in this query I could have done

| wins > 1000 clan=*Diablo*

Note searching field values in CQL is case sensitive and luckily both clans used a capital D. Since I don't use any regex stuffs in my queries I'll bring up a few things here. I could have invoked the regex engine and told it to look for the string "diablo" in a case insensitive manner like this

| wins > 1000 clan=/diablo/i

Note the forward slashes and the lower case i at the end. If I wanted to pull up the Diablos and say, LegendsOnly I could do any of the following to include a regex OR.

| wins> 1000 clan=*Diablo* or clan=LegendsOnly

| wins> 1000 
| in(field=clan, values=[*Diablo*, LegendsOnly])

| wins> 1000 clan=/(diablo|legendsonly)/i

What I don't know is if there is any value in doing (?:diablo|legendsonly) vs  (diablo|legendsonly). 

4. Clan Wins and Percent of Total Battles

$dfh_clan_leaderboard()
| foo := "x"
| groupBy([foo], function=[sum(wins, as = totalWins), groupBy([clan], function=collect([wins]))])
| percOfTotalWins := (wins/totalWins)*100
| round("percOfTotalWins")
| table([clan, wins, totalWins, percOfTotalWins], sortby=percOfTotalWins)

Here is where I saw a delta between CQL and SPL - eventstats. I love me some eventstats! I'm not sure how frequently it is used by the average Splunker /shrug. It lets you create statistical evaluations across your dataset as a new field - like stats and eval had a baby. In CQL you can nest groupBy statements within groupBy statements. GroupBy is largely a SPL stats equivalent. TBH I'm still wrapping my head around the nesting bit. 

The use case here is pretty simple - I want to have my query count the total number of wins so I can determine individual clan percent. Since I didn't have a secondary field to aggregate across all events, I created a new field that would be applied to all events (foo). Then within that same groupBy I simply pulled out the individual clan wins (collect ~ splunk stats values). There might be a better way to do what I did?

I'll call out then if you want your groupBy to do multiple functions or evaluations, you need to wrap your function in square brackets. Square brackets in CQL let the engine know it is dealing with an array. You will use this a good bit - for example look at the table command here. 

5. Clan Wins as Percent of Total Battles - the Pie Version

$dfh_clan_leaderboard()
| drop([finish_position, members])

Conceptually panel 4 and 5 are the same. I wanted to go through the gyrations in panel 4 to highlight how you can process the data. Here I'm simply calling up the data, keeping what I want, and by pivoting to a Pie chart letting the engine do the work. 

6 a&b - Contributors Relative to Wins

$dfh_clan_leaderboard()
| join(query={ $dfh_clan_efforts() | wins > 0 | groupBy([clan], function=count(as = contributors)) }, field=[clan], include=[contributors],  mode=left)

I really liked how the Splunk version of this turned out as I'm effectively looking at 4 dimensions of data at once. Splunk is also 20 yrs old this year and has a ton of iterative development.

What I'll highlight here from a visualization standpoint is with LogScale, as of this time, in order to use a bar chart you will need to use a groupBy statement in your query. You can't simply take the same data in tabular form and use that visualization. I thought about trying a scatter plot but wanted to keep the posts relatively the same for the 1s and 1s of readers who find this let alone flip back and forth between the SPL and CQL version of this post.

I will call out how I brought the two datasets together via join. I didn't use the CQL match command as I needed to perform some calculations before merging the data. I'm also doing a left, or outer, join vs inner. The difference is inner joins (regardless of language) are used when you want to only show results where results are the same. Left joins are when you still want to see all of the data from the initial portion of your query.

7 & 8 - Clan Chest Filled Distribution

$dfh_clan_leaderboard()
| full_chest := 1186
| perc_filled := (wins/full_chest)*100
| case{perc_filled >= 100 | perc_filled := 100; * | round(perc_filled)}
| case{ perc_filled >= 90 | foo := "01. 90-100"; perc_filled >=80 | foo := "02. 80-89"; perc_filled >= 70 | foo := "03. 70-79" ; perc_filled >= 60 | foo := "04. 60-69"; perc_filled >=50 | foo := "05. 50-59"; perc_filled >=40 | foo := "06. 40-49"; perc_filled >= 30 | foo := "07. 30-39"; perc_filled >=20 | foo := "08. 20-29" ; perc_filled > 10 | foo := "09. 10-19"; perc_filled >=0 | foo := "10. 0-9" ; * | foo := "fixme"}
| groupBy([foo], function=count(clan))
| sort(foo, order=asc)

Both of these panels are using the same query. I'm doing something here I like doing but haven't figured out a good way to explain. In effect find a value and then explore that value from a bucketized frequency perspective. Help? No? How about this


I first define how many wins fill a chest then figure out, from the 2 day PvP wins, how filled individual clan's chest would be as a percentage (perc_filled), Now I want to bucketize across the dataset the clan perc_filled (foo) to then aggregate on that field. In other words, how many clans fully filled their chest, how many filled it less than 10%, etc. I want to bucketize this as visually parsing 10 data points is often better than all data points. In my case that is only 236 but what if it were a million? I've arbitrability picked 10, it could have been 5 or 20 or whatever.

A sharp eye will note nuances of case statements: the use of curly brace, pipes, and semicolons. For those that don't otherwise know, when you use case statements an event is evaluated left to right. As soon as an argument evaluates as true it breaks out of the evaluation. This is why I can walk down numerically with my greater than symbols.

The reason the 'foo' buckets look goofy is I wanted to display the buckets I had created in a particular order. Many engines have sorting issues when you combine character, integer, and special characters. I prepended my order to help the sorting portion of the code. 

I was somewhat surprised the pie chart would only display in descending % but that is what it is I guess. I also wanted to highlight here how you can open up the inner radius of the pie which is kinda neat if you are into that look.

 9. Member Participation

$dfh_clan_efforts()
| wins > 0
| groupBy([clan], function=[sum("wins", as=clan_wins), count(clan_member, distinct=true, as=contributing_members), avg(wins, as=avgMemberWins)])
| round("avgMemberWins")
| match(file="clan_leaderboard.csv", field="clan", strict=false)
| table([clan, finish_position, clan_wins, contributing_members, avgMemberWins], sortby=clan_wins, order=desc)
| default(value="null", field=[finish_position])
| case{ finish_position="null" | finish_position := 60; * | finish_position := finish_position }

I'm flipping over to the individual contribution dataset here to see how many members participated and show that relative clan finish position. This is interesting to me from the perspective of who is pulling their weight? I'm similarly interested in knowing what the average wins across participating members. Honestly averages are overrated and box plot type numbers are the better way to go. Or at least look at the average and the median. Those are separate discussions though. 

In my match statement you will see strict=false. This is somewhat similar to a left join in that I want to keep my original dataset even if there isn't a match from the secondary csv I'm pulling in. On that note I did upload the actual csv into LogScale in the Files portion of my Repo's nav bar. The use of match can allow users to enrich data with a static dataset. You just can't pull up that dataset within a search on its own.

Because of how I collected the data there is a hole in the finish position for Valhalla. The last two lines of the query adjust the data for that. I haven't found a clean way to identify and work with nulls in LogScale yet other than this two stepper. In this case 'default' operates like Splunk's fillnull.

10 - Top 10 Hitters and Clan Representation

$dfh_clan_efforts()
| sort(wins, order=asc, limit=20000)
| table([clan, clan_member, wins], sortby=wins, order=desc, limit=10) | join(query={$dfh_clan_efforts() | table([clan, clan_member, wins], sortby=wins, order=desc, limit=10)
| groupBy([clan], function=count(as="clan representation"))}, field=[clan], include="clan representation")
| table([clan, clan_member, "clan representation", wins])

The first part is straight forward enough - show me the top 10 individual finishers/contributors. The default for LogScale's sort function is only 200. An order of magnitude here is a bit high but I wanted to figure out what the max is was/currently is.

Now I want to see how many in the top 10 were in the same clan AND I wanted to display the data like I am. I tried multiple times with nested groupBy statements but nothing worked for me. That's fine, I'll use join. You'll see the joined query looks pretty similar to the first search - get the top 10 finishers, then do a count by clan. With joins you need to include an 'include' argument to tell LogScale what you are looking to bring over. Then its just a matter of using table to display the data in the filed order I want.

That's it! 

Hopefully people find this valuable. If you have questions, comments, or alternate queries I'm all ears!

I suppose I haven't really talked about the dashboard layout itself. As a personal taste thing I like to start with high level aggregations at the top with both widget size and granularity increasing as you work down. For me that helps set the stage and as I start wondering about some of the granularities they start to become apparent. Separately I like telling folks that especially for singular dashboard panels try to think about what the audience's first question will be and work to answer that. My goto is something like failed auth. It's great that you can generate a list of people with the highest numbers of failed authentications. A security analyst will now want to know things like was that on one system or many, did it happen all at once or over time, is it still going on? Try to develop your singular panels or if you are using a full dashboard to answer those questions vs making the analyst go somewhere else to find them out. Saves time and hassle.

Raw data - copy/paste these into your LogScale instance, then save them as searches.

Individual efforts

createEvents(["Diablo2,Diablo2_1,504",
"Diablo2,Diablo2_2,500",
"Diablo2,Diablo2_3,349",
"Diablo2,Diablo2_4,335",
"Diablo2,Diablo2_5,222",
"Diablo2,Diablo2_6,209",
"Diablo2,Diablo2_7,177",
"Diablo2,Diablo2_8,152",
"Diablo2,Diablo2_9,137",
"Diablo2,Diablo2_10,129",
"Diablo2,Diablo2_11,124",
"Diablo2,Diablo2_12,118",
"Diablo2,Diablo2_13,116",
"Diablo2,Diablo2_14,102",
"Diablo2,Diablo2_15,85",
"Diablo2,Diablo2_16,78",
"Diablo2,Diablo2_17,75",
"Diablo2,Diablo2_18,74",
"Diablo2,Diablo2_19,67",
"Diablo2,Diablo2_20,59",
"Diablo2,Diablo2_21,56",
"Diablo2,Diablo2_22,56",
"Diablo2,Diablo2_23,56",
"Diablo2,Diablo2_24,52",
"Diablo2,Diablo2_25,51",
"Diablo2,Diablo2_26,51",
"Diablo2,Diablo2_27,49",
"Diablo2,Diablo2_28,43",
"Diablo2,Diablo2_29,41",
"Diablo2,Diablo2_30,39",
"Diablo2,Diablo2_31,34",
"Diablo2,Diablo2_32,31",
"Diablo2,Diablo2_33,28",
"Diablo2,Diablo2_34,24",
"Diablo2,Diablo2_35,24",
"Diablo2,Diablo2_36,18",
"Diablo2,Diablo2_37,17",
"Diablo2,Diablo2_38,16",
"Diablo2,Diablo2_39,14",
"Diablo2,Diablo2_40,9",
"Diablo2,Diablo2_41,8",
"Diablo2,Diablo2_42,5",
"Diablo2,Diablo2_43,5",
"Diablo2,Diablo2_44,3",
"Diablo2,Diablo2_45,1",
"SpawnsofDiablo,SpawnsofDiablo_1,488",
"SpawnsofDiablo,SpawnsofDiablo_2,307",
"SpawnsofDiablo,SpawnsofDiablo_3,272",
"SpawnsofDiablo,SpawnsofDiablo_4,266",
"SpawnsofDiablo,SpawnsofDiablo_5,199",
"SpawnsofDiablo,SpawnsofDiablo_6,171",
"SpawnsofDiablo,SpawnsofDiablo_7,166",
"SpawnsofDiablo,SpawnsofDiablo_8,161",
"SpawnsofDiablo,SpawnsofDiablo_9,151",
"SpawnsofDiablo,SpawnsofDiablo_10,138",
"SpawnsofDiablo,SpawnsofDiablo_11,130",
"SpawnsofDiablo,SpawnsofDiablo_12,120",
"SpawnsofDiablo,SpawnsofDiablo_13,110",
"SpawnsofDiablo,SpawnsofDiablo_14,103",
"SpawnsofDiablo,SpawnsofDiablo_15,98",
"SpawnsofDiablo,SpawnsofDiablo_16,80",
"SpawnsofDiablo,SpawnsofDiablo_17,78",
"SpawnsofDiablo,SpawnsofDiablo_18,72",
"SpawnsofDiablo,SpawnsofDiablo_19,62",
"SpawnsofDiablo,SpawnsofDiablo_20,53",
"SpawnsofDiablo,SpawnsofDiablo_21,51",
"SpawnsofDiablo,SpawnsofDiablo_22,49",
"SpawnsofDiablo,SpawnsofDiablo_23,49",
"SpawnsofDiablo,SpawnsofDiablo_24,48",
"SpawnsofDiablo,SpawnsofDiablo_25,44",
"SpawnsofDiablo,SpawnsofDiablo_26,38",
"SpawnsofDiablo,SpawnsofDiablo_27,32",
"SpawnsofDiablo,SpawnsofDiablo_28,32",
"SpawnsofDiablo,SpawnsofDiablo_29,27",
"SpawnsofDiablo,SpawnsofDiablo_30,27",
"SpawnsofDiablo,SpawnsofDiablo_31,26",
"SpawnsofDiablo,SpawnsofDiablo_32,24",
"SpawnsofDiablo,SpawnsofDiablo_33,23",
"SpawnsofDiablo,SpawnsofDiablo_34,23",
"SpawnsofDiablo,SpawnsofDiablo_35,22",
"SpawnsofDiablo,SpawnsofDiablo_36,21",
"SpawnsofDiablo,SpawnsofDiablo_37,17",
"SpawnsofDiablo,SpawnsofDiablo_38,13",
"SpawnsofDiablo,SpawnsofDiablo_39,13",
"SpawnsofDiablo,SpawnsofDiablo_40,11",
"SpawnsofDiablo,SpawnsofDiablo_41,11",
"SpawnsofDiablo,SpawnsofDiablo_42,11",
"SpawnsofDiablo,SpawnsofDiablo_43,9",
"SpawnsofDiablo,SpawnsofDiablo_44,9",
"SpawnsofDiablo,SpawnsofDiablo_45,8",
"SpawnsofDiablo,SpawnsofDiablo_46,5",
"SpawnsofDiablo,SpawnsofDiablo_47,3",
"SpawnsofDiablo,SpawnsofDiablo_48,2",
"SpawnsofDiablo,SpawnsofDiablo_49,0",
"LegendsOnly,LegendsOnly_1,560",
"LegendsOnly,LegendsOnly_2,399",
"LegendsOnly,LegendsOnly_3,190",
"LegendsOnly,LegendsOnly_4,147",
"LegendsOnly,LegendsOnly_5,131",
"LegendsOnly,LegendsOnly_6,102",
"LegendsOnly,LegendsOnly_7,89",
"LegendsOnly,LegendsOnly_8,77",
"LegendsOnly,LegendsOnly_9,53",
"LegendsOnly,LegendsOnly_10,52",
"LegendsOnly,LegendsOnly_11,49",
"LegendsOnly,LegendsOnly_12,48",
"LegendsOnly,LegendsOnly_13,43",
"LegendsOnly,LegendsOnly_14,40",
"LegendsOnly,LegendsOnly_15,38",
"LegendsOnly,LegendsOnly_16,37",
"LegendsOnly,LegendsOnly_17,37",
"LegendsOnly,LegendsOnly_18,30",
"LegendsOnly,LegendsOnly_19,27",
"LegendsOnly,LegendsOnly_20,22",
"LegendsOnly,LegendsOnly_21,19",
"LegendsOnly,LegendsOnly_22,18",
"LegendsOnly,LegendsOnly_23,17",
"LegendsOnly,LegendsOnly_24,17",
"LegendsOnly,LegendsOnly_25,16",
"LegendsOnly,LegendsOnly_26,16",
"LegendsOnly,LegendsOnly_27,16",
"LegendsOnly,LegendsOnly_28,15",
"LegendsOnly,LegendsOnly_29,15",
"LegendsOnly,LegendsOnly_30,14",
"LegendsOnly,LegendsOnly_31,14",
"LegendsOnly,LegendsOnly_32,14",
"LegendsOnly,LegendsOnly_33,12",
"LegendsOnly,LegendsOnly_34,11",
"LegendsOnly,LegendsOnly_35,9",
"LegendsOnly,LegendsOnly_36,9",
"LegendsOnly,LegendsOnly_37,9",
"LegendsOnly,LegendsOnly_38,9",
"LegendsOnly,LegendsOnly_39,8",
"LegendsOnly,LegendsOnly_40,7",
"LegendsOnly,LegendsOnly_41,7",
"LegendsOnly,LegendsOnly_42,7",
"LegendsOnly,LegendsOnly_43,7",
"LegendsOnly,LegendsOnly_44,7",
"LegendsOnly,LegendsOnly_45,4",
"LegendsOnly,LegendsOnly_46,4",
"LegendsOnly,LegendsOnly_47,4",
"LegendsOnly,LegendsOnly_48,3",
"LegendsOnly,LegendsOnly_49,3",
"LegendsOnly,LegendsOnly_50,0",
"Worldwarriors,Worldwarriors_1,167",
"Worldwarriors,Worldwarriors_2,66",
"Worldwarriors,Worldwarriors_3,58",
"Worldwarriors,Worldwarriors_4,50",
"Worldwarriors,Worldwarriors_5,33",
"Worldwarriors,Worldwarriors_6,29",
"Worldwarriors,Worldwarriors_7,27",
"Worldwarriors,Worldwarriors_8,24",
"Worldwarriors,Worldwarriors_9,21",
"Worldwarriors,Worldwarriors_10,21",
"Worldwarriors,Worldwarriors_11,19",
"Worldwarriors,Worldwarriors_12,16",
"Worldwarriors,Worldwarriors_13,15",
"Worldwarriors,Worldwarriors_14,13",
"Worldwarriors,Worldwarriors_15,12",
"Worldwarriors,Worldwarriors_16,12",
"Worldwarriors,Worldwarriors_17,11",
"Worldwarriors,Worldwarriors_18,11",
"Worldwarriors,Worldwarriors_19,11",
"Worldwarriors,Worldwarriors_20,10",
"Worldwarriors,Worldwarriors_21,10",
"Worldwarriors,Worldwarriors_22,8",
"Worldwarriors,Worldwarriors_23,7",
"Worldwarriors,Worldwarriors_24,7",
"Worldwarriors,Worldwarriors_25,6",
"Worldwarriors,Worldwarriors_26,6",
"Worldwarriors,Worldwarriors_27,6",
"Worldwarriors,Worldwarriors_28,6",
"Worldwarriors,Worldwarriors_29,5",
"Worldwarriors,Worldwarriors_30,5",
"Worldwarriors,Worldwarriors_31,5",
"Worldwarriors,Worldwarriors_32,4",
"Worldwarriors,Worldwarriors_33,3",
"Worldwarriors,Worldwarriors_34,3",
"Worldwarriors,Worldwarriors_35,2",
"Worldwarriors,Worldwarriors_36,2",
"Worldwarriors,Worldwarriors_37,2",
"Worldwarriors,Worldwarriors_38,2",
"Worldwarriors,Worldwarriors_39,1",
"Worldwarriors,Worldwarriors_40,1",
"Worldwarriors,Worldwarriors_41,0",
"Worldwarriors,Worldwarriors_42,0",
"Worldwarriors,Worldwarriors_43,0",
"Worldwarriors,Worldwarriors_44,0",
"Worldwarriors,Worldwarriors_45,0",
"Worldwarriors,Worldwarriors_46,0",
"Worldwarriors,Worldwarriors_47,0",
"Worldwarriors,Worldwarriors_48,0",
"Worldwarriors,Worldwarriors_49,0",
"Worldwarriors,Worldwarriors_50,0",
"ColoradoCasual,ColoradoCasual_1,23",
"ColoradoCasual,ColoradoCasual_2,21",
"ColoradoCasual,ColoradoCasual_3,21",
"ColoradoCasual,ColoradoCasual_4,20",
"ColoradoCasual,ColoradoCasual_5,19",
"ColoradoCasual,ColoradoCasual_6,17",
"ColoradoCasual,ColoradoCasual_7,16",
"ColoradoCasual,ColoradoCasual_8,12",
"ColoradoCasual,ColoradoCasual_9,11",
"ColoradoCasual,ColoradoCasual_10,10",
"ColoradoCasual,ColoradoCasual_11,10",
"ColoradoCasual,ColoradoCasual_12,9",
"ColoradoCasual,ColoradoCasual_13,9",
"ColoradoCasual,ColoradoCasual_14,8",
"ColoradoCasual,ColoradoCasual_15,8",
"ColoradoCasual,ColoradoCasual_16,7",
"ColoradoCasual,ColoradoCasual_17,7",
"ColoradoCasual,ColoradoCasual_18,7",
"ColoradoCasual,ColoradoCasual_19,7",
"ColoradoCasual,ColoradoCasual_20,7",
"ColoradoCasual,ColoradoCasual_21,6",
"ColoradoCasual,ColoradoCasual_22,5",
"ColoradoCasual,ColoradoCasual_23,5",
"ColoradoCasual,ColoradoCasual_24,5",
"ColoradoCasual,ColoradoCasual_25,4",
"ColoradoCasual,ColoradoCasual_26,4",
"ColoradoCasual,ColoradoCasual_27,3",
"ColoradoCasual,ColoradoCasual_28,1",
"ColoradoCasual,ColoradoCasual_29,1",
"ColoradoCasual,ColoradoCasual_30,0",
"ColoradoCasual,ColoradoCasual_31,0",
"ColoradoCasual,ColoradoCasual_32,0",
"ColoradoCasual,ColoradoCasual_33,0",
"ColoradoCasual,ColoradoCasual_34,0",
"ColoradoCasual,ColoradoCasual_35,0",
"ColoradoCasual,ColoradoCasual_36,0",
"ColoradoCasual,ColoradoCasual_37,0",
"ColoradoCasual,ColoradoCasual_38,0",
"ColoradoCasual,ColoradoCasual_39,0",
"ColoradoCasual,ColoradoCasual_40,0",
"ColoradoCasual,ColoradoCasual_41,0",
"ColoradoCasual,ColoradoCasual_42,0",
"ColoradoCasual,ColoradoCasual_43,0",
"ColoradoCasual,ColoradoCasual_44,0",
"ColoradoCasual,ColoradoCasual_45,0",
"ColoradoCasual,ColoradoCasual_46,0",
"ColoradoCasual,ColoradoCasual_47,0",
"ColoradoCasual,ColoradoCasual_48,0",
"ColoradoCasual,ColoradoCasual_49,0",
"ColoradoCasual,ColoradoCasual_50,0",
"Armyofall,Armyofall_1,34",
"Armyofall,Armyofall_2,30",
"Armyofall,Armyofall_3,25",
"Armyofall,Armyofall_4,14",
"Armyofall,Armyofall_5,13",
"Armyofall,Armyofall_6,11",
"Armyofall,Armyofall_7,11",
"Armyofall,Armyofall_8,8",
"Armyofall,Armyofall_9,7",
"Armyofall,Armyofall_10,5",
"Armyofall,Armyofall_11,4",
"Armyofall,Armyofall_12,3",
"Armyofall,Armyofall_13,2",
"Armyofall,Armyofall_14,2",
"Armyofall,Armyofall_15,2",
"Armyofall,Armyofall_16,2",
"Armyofall,Armyofall_17,2",
"Armyofall,Armyofall_18,2",
"Armyofall,Armyofall_19,1",
"Armyofall,Armyofall_20,1",
"Armyofall,Armyofall_21,1",
"Armyofall,Armyofall_22,0",
"Armyofall,Armyofall_23,0",
"Armyofall,Armyofall_24,0",
"Armyofall,Armyofall_25,0",
"Armyofall,Armyofall_26,0",
"Armyofall,Armyofall_27,0",
"Armyofall,Armyofall_28,0",
"Armyofall,Armyofall_29,0",
"Armyofall,Armyofall_30,0",
"Armyofall,Armyofall_31,0",
"Armyofall,Armyofall_32,0",
"Armyofall,Armyofall_33,0",
"Armyofall,Armyofall_34,0",
"Armyofall,Armyofall_35,0",
"Armyofall,Armyofall_36,0",
"Armyofall,Armyofall_37,0",
"Armyofall,Armyofall_38,0",
"Armyofall,Armyofall_39,0",
"Armyofall,Armyofall_40,0",
"Armyofall,Armyofall_41,0",
"Armyofall,Armyofall_42,0",
"Armyofall,Armyofall_43,0",
"Armyofall,Armyofall_44,0",
"Armyofall,Armyofall_45,0",
"Armyofall,Armyofall_46,0",
"Armyofall,Armyofall_47,0",
"Armyofall,Armyofall_48,0",
"Armyofall,Armyofall_49,0",
"Armyofall,Armyofall_50,0",
"HordeSmashers,HordSmashers_1,17",
"HordeSmashers,HordSmashers_2,16",
"HordeSmashers,HordSmashers_3,14",
"HordeSmashers,HordSmashers_4,11",
"HordeSmashers,HordSmashers_5,10",
"HordeSmashers,HordSmashers_6,7",
"HordeSmashers,HordSmashers_7,7",
"HordeSmashers,HordSmashers_8,3",
"HordeSmashers,HordSmashers_9,3",
"HordeSmashers,HordSmashers_10,2",
"HordeSmashers,HordSmashers_11,2",
"HordeSmashers,HordSmashers_12,2",
"HordeSmashers,HordSmashers_13,2",
"HordeSmashers,HordSmashers_14,2",
"HordeSmashers,HordSmashers_15,1",
"HordeSmashers,HordSmashers_16,1",
"HordeSmashers,HordSmashers_17,1",
"HordeSmashers,HordSmashers_18,1",
"HordeSmashers,HordSmashers_19,1",
"HordeSmashers,HordSmashers_20,0",
"HordeSmashers,HordSmashers_21,0",
"HordeSmashers,HordSmashers_22,0",
"HordeSmashers,HordSmashers_23,0",
"HordeSmashers,HordSmashers_24,0",
"HordeSmashers,HordSmashers_25,0",
"HordeSmashers,HordSmashers_26,0",
"HordeSmashers,HordSmashers_27,0",
"HordeSmashers,HordSmashers_28,0",
"HordeSmashers,HordSmashers_29,0",
"HordeSmashers,HordSmashers_30,0",
"HordeSmashers,HordSmashers_31,0",
"HordeSmashers,HordSmashers_32,0",
"HordeSmashers,HordSmashers_33,0",
"HordeSmashers,HordSmashers_34,0",
"HordeSmashers,HordSmashers_35,0",
"HordeSmashers,HordSmashers_36,0",
"HordeSmashers,HordSmashers_37,0",
"HordeSmashers,HordSmashers_38,0",
"HordeSmashers,HordSmashers_39,0",
"HordeSmashers,HordSmashers_40,0",
"HordeSmashers,HordSmashers_41,0",
"HordeSmashers,HordSmashers_42,0",
"HordeSmashers,HordSmashers_43,0",
"HordeSmashers,HordSmashers_44,0",
"HordeSmashers,HordSmashers_45,0",
"HordeSmashers,HordSmashers_46,0",
"HordeSmashers,HordSmashers_47,0",
"HordeSmashers,HordSmashers_48,0",
"HordeSmashers,HordSmashers_49,0",
"HordeSmashers,HordSmashers_50,0",
"SinCityKnights,SinCityKnights_1,14",
"SinCityKnights,SinCityKnights_2,14",
"SinCityKnights,SinCityKnights_3,10",
"SinCityKnights,SinCityKnights_4,8",
"SinCityKnights,SinCityKnights_5,7",
"SinCityKnights,SinCityKnights_6,5",
"SinCityKnights,SinCityKnights_7,4",
"SinCityKnights,SinCityKnights_8,3",
"SinCityKnights,SinCityKnights_9,3",
"SinCityKnights,SinCityKnights_10,3",
"SinCityKnights,SinCityKnights_11,3",
"SinCityKnights,SinCityKnights_12,2",
"SinCityKnights,SinCityKnights_13,1",
"SinCityKnights,SinCityKnights_14,1",
"SinCityKnights,SinCityKnights_15,1",
"SinCityKnights,SinCityKnights_16,1",
"SinCityKnights,SinCityKnights_17,1",
"SinCityKnights,SinCityKnights_18,1",
"SinCityKnights,SinCityKnights_19,1",
"SinCityKnights,SinCityKnights_20,0",
"SinCityKnights,SinCityKnights_21,0",
"SinCityKnights,SinCityKnights_22,0",
"SinCityKnights,SinCityKnights_23,0",
"SinCityKnights,SinCityKnights_24,0",
"SinCityKnights,SinCityKnights_25,0",
"SinCityKnights,SinCityKnights_26,0",
"SinCityKnights,SinCityKnights_27,0",
"SinCityKnights,SinCityKnights_28,0",
"SinCityKnights,SinCityKnights_29,0",
"SinCityKnights,SinCityKnights_30,0",
"SinCityKnights,SinCityKnights_31,0",
"SinCityKnights,SinCityKnights_32,0",
"SinCityKnights,SinCityKnights_33,0",
"SinCityKnights,SinCityKnights_34,0",
"SinCityKnights,SinCityKnights_35,0",
"SinCityKnights,SinCityKnights_36,0",
"SinCityKnights,SinCityKnights_37,0",
"SinCityKnights,SinCityKnights_38,0",
"SinCityKnights,SinCityKnights_39,0",
"SinCityKnights,SinCityKnights_40,0",
"SinCityKnights,SinCityKnights_41,0",
"SinCityKnights,SinCityKnights_42,0",
"SinCityKnights,SinCityKnights_43,0",
"SinCityKnights,SinCityKnights_44,0",
"SinCityKnights,SinCityKnights_45,0",
"SinCityKnights,SinCityKnights_46,0",
"SinCityKnights,SinCityKnights_47,0",
"SinCityKnights,SinCityKnights_48,0",
"SinCityKnights,SinCityKnights_49,0",
"SinCityKnights,SinCityKnights_50,0",
"Valhalla,Valhalla_1,10",
"Valhalla,Valhalla_2,9",
"Valhalla,Valhalla_3,9",
"Valhalla,Valhalla_4,8",
"Valhalla,Valhalla_5,6",
"Valhalla,Valhalla_6,4",
"Valhalla,Valhalla_7,2",
"Valhalla,Valhalla_8,2",
"Valhalla,Valhalla_9,2",
"Valhalla,Valhalla_10,2",
"Valhalla,Valhalla_11,2",
"Valhalla,Valhalla_12,1",
"Valhalla,Valhalla_13,0",
"Valhalla,Valhalla_14,0",
"Valhalla,Valhalla_15,0",
"Valhalla,Valhalla_16,0",
"Valhalla,Valhalla_17,0",
"Valhalla,Valhalla_18,0",
"Valhalla,Valhalla_19,0",
"Valhalla,Valhalla_20,0",
"Valhalla,Valhalla_21,0",
"Valhalla,Valhalla_22,0",
"Valhalla,Valhalla_23,0",
"Valhalla,Valhalla_24,0",
"Valhalla,Valhalla_25,0",
"Valhalla,Valhalla_26,0",
"Valhalla,Valhalla_27,0",
"Valhalla,Valhalla_28,0",
"Valhalla,Valhalla_29,0",
"Valhalla,Valhalla_30,0",
"Valhalla,Valhalla_31,0",
"Valhalla,Valhalla_32,0",
"Valhalla,Valhalla_33,0",
"Valhalla,Valhalla_34,0",
"Valhalla,Valhalla_35,0",
"Valhalla,Valhalla_36,0",
"Valhalla,Valhalla_37,0",
"Valhalla,Valhalla_38,0",
"Valhalla,Valhalla_39,0",
"Valhalla,Valhalla_40,0",
"Valhalla,Valhalla_41,0",
"Valhalla,Valhalla_42,0",
"Valhalla,Valhalla_43,0",
"Valhalla,Valhalla_44,0",
"Valhalla,Valhalla_45,0",
"Valhalla,Valhalla_46,0",
"Valhalla,Valhalla_47,0",
"Valhalla,Valhalla_48,0",
"Valhalla,Valhalla_49,0",
"Valhalla,Valhalla_50,0"])
| parseCsv(columns=["clan", "clan_member", "wins"])
| drop([@rawstring, @timestamp.nanos, @timestamp])

Clan Leaderboard
createEvents(["Diablo2,1,49,4439",
"SpawnsofDiablo,2,50,3883",
"LegendsOnly,3,50,2536",
"Assassins,4,50,2032",
"Deplorables,5,50,1119",
"WeAreGroot,6,50,1018",
"PlanetExpress,7,50,802",
"Resurrected,8,45,770",
"Worldwarriors,9,50,656",
"imperialguard2,10,48,652",
"Heathens,11,50,567",
"Covid,12,50,450",
"Sofaklanen,13,50,382",
"ActiveOnly,14,50,369",
"HiddenLeaf,15,50,303",
"TeamQc,16,50,298",
"F3ARLESS,17,50,297",
"Revansheer,18,50,295",
"CatchThzHandz,19,50,277",
"ColoradoCasual,20,50,274",
"NuBeginnings,21,50,271",
"MisfitToys,22,50,270",
"WolfiesClan,23,50,256",
"DutchTigers,24,49,241",
"ZeroFukGiven,25,50,237",
"SpectralSpartans,26,50,229",
"Fighters,27,50,215",
"KINGSnQUEENS,28,50,206",
"FerdaBoys,29,50,192",
"Armyofall,30,48,165",
"TurtleGang,31,50,149",
"Logitek,32,50,147",
"BreganDaerthe,33,44,146",
"NorthernElysia,34,48,138",
"WarDogz,35,48,132",
"Exile,36,50,128",
"Fusion,37,50,121",
"TheWarForged,38,50,120",
"13thLegion,39,50,102",
"HordeSmashers,40,50,95",
"Dreamwalkers,41,50,90",
"Akatsuki,42,50,89",
"DarkfireMambas,43,50,88",
"Sparrago,44,50,87",
"Raiders,45,50,84",
"JustForFun,46,50,82",
"WARHAMMER,47,50,77",
"CustardSGood,48,50,76",
"SinCityKnights,49,50,75",
"BigChunges,50,50,74",
"clan_51,51,50,70",
"clan_52,52,50,69",
"clan_53,53,50,66",
"clan_54,54,50,65",
"clan_55,55,50,64",
"clan_56,56,50,60",
"clan_57,57,50,59",
"clan_58,58,50,57",
"clan_59,59,50,56",
"clan_60,60,50,54",
"clan_61,61,50,53",
"clan_62,62,50,53",
"clan_63,63,50,51",
"clan_64,64,47,49",
"clan_65,65,50,48",
"clan_66,66,50,48",
"clan_67,67,50,47",
"clan_68,68,32,42",
"clan_69,69,50,40",
"clan_70,70,50,39",
"clan_71,71,50,38",
"clan_72,72,50,38",
"clan_73,73,19,37",
"clan_74,74,50,36",
"clan_75,75,50,36",
"clan_76,76,50,33",
"clan_77,77,50,33",
"clan_78,78,50,33",
"clan_79,79,50,32",
"clan_80,80,33,30",
"clan_81,81,50,29",
"clan_82,82,50,29",
"clan_83,83,50,29",
"clan_84,84,50,27",
"clan_85,85,50,26",
"clan_86,86,50,25",
"clan_87,87,50,25",
"clan_88,88,50,25",
"clan_89,89,50,24",
"clan_90,90,50,21",
"clan_91,91,50,20",
"clan_92,92,50,20",
"clan_93,93,50,19",
"clan_94,94,12,18",
"clan_95,95,15,17",
"clan_96,96,28,16",
"clan_97,97,50,16",
"clan_98,98,18,16",
"clan_99,99,50,16",
"clan_100,100,50,16",
"clan_101,101,22,16",
"clan_102,102,50,16",
"clan_103,103,43,15",
"clan_104,104,50,15",
"clan_105,105,22,15",
"clan_106,106,50,15",
"clan_107,107,50,15",
"clan_108,108,50,14",
"clan_109,109,50,14",
"clan_110,110,50,14",
"clan_111,111,50,14",
"clan_112,112,50,14",
"clan_113,113,50,14",
"clan_114,114,50,14",
"clan_115,115,50,13",
"clan_116,116,49,13",
"clan_117,117,50,13",
"clan_118,118,48,13",
"clan_119,119,50,13",
"clan_120,120,50,12",
"clan_121,121,50,12",
"clan_122,122,23,12",
"clan_123,123,50,12",
"clan_124,124,50,12",
"clan_125,125,13,11",
"clan_126,126,50,11",
"clan_127,127,50,11",
"clan_128,128,50,11",
"clan_129,129,50,11",
"clan_130,130,50,11",
"clan_131,131,50,10",
"clan_132,132,50,10",
"clan_133,133,50,10",
"clan_134,134,50,10",
"clan_135,135,50,10",
"clan_136,136,50,10",
"clan_137,137,50,10",
"clan_138,138,50,10",
"clan_139,139,50,9",
"clan_140,140,50,9",
"clan_141,141,50,8",
"clan_142,142,50,8",
"clan_143,143,50,8",
"clan_144,144,50,8",
"clan_145,145,50,8",
"clan_146,146,50,8",
"clan_147,147,50,8",
"clan_148,148,50,8",
"clan_149,149,50,8",
"clan_150,150,50,7"])
| parseCsv(columns=["clan", "finish_position", "members", "wins"])
| drop([@rawstring, @timestamp, @timestamp.nanos])








No comments:

Post a Comment