LuaProfiler and logging

Place to get help with not working mods / modding interface.
orzelek
Smart Inserter
Smart Inserter
Posts: 3928
Joined: Fri Apr 03, 2015 10:20 am
Contact:

LuaProfiler and logging

Post by orzelek »

Can someone give me some hints how to store output of those into script output?
I have a logger in RSO that accepts text and dumps all of it after a command to file. But I doesn't seem to be able to convert profiler to string in nice way.
Only way that seems to work is like this:
log{"Search time __1__ spawn time __2__ ", scanProfiler, placeProfiler}
and it writes something to log file but it's not fully working:
313.553 Script @__rso-mod__/control.lua:733: Unknown key: "Search time Duration: 234.668400ms spawn time 2 "
It seems that more then one of those doesn't want to work correctly?

I'd really prefer to be able to write it to script output as string even with risk of desyncs - I have a lot of debug output there and separate stuff on log() is hard to reconcile with it.
Bilka
Factorio Staff
Factorio Staff
Posts: 3464
Joined: Sat Aug 13, 2016 9:20 am
Contact:

Re: LuaProfiler and logging

Post by Bilka »

I'm an admin over at https://wiki.factorio.com. Feel free to contact me if there's anything wrong (or right) with it.
orzelek
Smart Inserter
Smart Inserter
Posts: 3928
Joined: Fri Apr 03, 2015 10:20 am
Contact:

Re: LuaProfiler and logging

Post by orzelek »

The example with __1__ and __2__ in same string is exaclty what I used and as you can see the result was not as expected since second substitution didn't work.
And I don't think that adding a new localized string to mod for debugging purposes is the intended solution?
If thats the case then it's quite a convoluted way to do this.
User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5211
Joined: Tue Jul 12, 2016 9:03 am
Contact:

Re: LuaProfiler and logging

Post by eradicator »

orzelek wrote: Wed Aug 28, 2019 10:40 pm The example with __1__ and __2__ in same string is exaclty what I used
Templates can not be defined at runtime, so...
orzelek wrote: Wed Aug 28, 2019 10:40 pm And I don't think that adding a new localized string to mod for debugging purposes is the intended solution?
Yes, that is exactly what you'll have to do.
Personally i use a generic

Code: Select all

[whatever]
mergetwo=__1____2__
mergethree=__1____2____3___
template to get around this engine limitation.
Last edited by eradicator on Thu Aug 29, 2019 10:35 am, edited 1 time in total.
Author of: Belt Planner, Hand Crank Generator, Screenshot Maker, /sudo and more.
Mod support languages: 日本語, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.
User avatar
Klonan
Factorio Staff
Factorio Staff
Posts: 5412
Joined: Sun Jan 11, 2015 2:09 pm
Contact:

Re: LuaProfiler and logging

Post by Klonan »

orzelek wrote: Wed Aug 28, 2019 8:23 pm Can someone give me some hints how to store output of those into script output?
I have a logger in RSO that accepts text and dumps all of it after a command to file. But I doesn't seem to be able to convert profiler to string in nice way.
Only way that seems to work is like this:
log{"Search time __1__ spawn time __2__ ", scanProfiler, placeProfiler}
and it writes something to log file but it's not fully working:
313.553 Script @__rso-mod__/control.lua:733: Unknown key: "Search time Duration: 234.668400ms spawn time 2 "
It seems that more then one of those doesn't want to work correctly?

I'd really prefer to be able to write it to script output as string even with risk of desyncs - I have a lot of debug output there and separate stuff on log() is hard to reconcile with it.
You need to do:


log{"", "Search time __1__ spawn time __2__ ", scanProfiler, placeProfiler}
User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5211
Joined: Tue Jul 12, 2016 9:03 am
Contact:

Re: LuaProfiler and logging

Post by eradicator »

Klonan wrote: Thu Aug 29, 2019 10:35 am log{"", "Search time __1__ spawn time __2__ ", scanProfiler, placeProfiler}
How does that work? When i try it:

Code: Select all

/c log{"",'one __1__ two __2__',{'item-name.iron-plate'},game.create_profiler()}

>>one __1__ two __2__Iron plateElapsed: 0.024375ms
Author of: Belt Planner, Hand Crank Generator, Screenshot Maker, /sudo and more.
Mod support languages: 日本語, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.
User avatar
Klonan
Factorio Staff
Factorio Staff
Posts: 5412
Joined: Sun Jan 11, 2015 2:09 pm
Contact:

Re: LuaProfiler and logging

Post by Klonan »

eradicator wrote: Thu Aug 29, 2019 10:42 am
Klonan wrote: Thu Aug 29, 2019 10:35 am log{"", "Search time __1__ spawn time __2__ ", scanProfiler, placeProfiler}
How does that work? When i try it:

Code: Select all

/c log{"",'one __1__ two __2__',{'item-name.iron-plate'},game.create_profiler()}

>>one __1__ two __2__Iron plateElapsed: 0.024375ms
Ah right, I was only looking at the 'Unknown key' issue.

Yea right now, it is not possible to use the 'parameter replacement' system with literal strings in this way
User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5211
Joined: Tue Jul 12, 2016 9:03 am
Contact:

Re: LuaProfiler and logging

Post by eradicator »

Klonan wrote: Thu Aug 29, 2019 10:47 am Yea right now, it is not possible to use the 'parameter replacement' system with literal strings in this way
As a hacky-wacky-workaround, would it be realistic to have mergetwo (see post above) or similar added to the official english locale? And maybe even an official function that makes it easily usable? My current implementation is a variable argument function that uses nine predefined mergers to construct a nested locale table.

Code: Select all

---merges an arbitrary number of arguments into a locale compatible table
---because factorio doesn't have simple mergine of locale strings built in...
--@args arbitrary strings or locale-compatible tables. or a single table of arguments.
function liblocale.merge(...)

  local args = {...}
  
  --forgot arguments?
  if #args == 0 then
    stop('Too few locale.merge() arguments.')
    end
  
  --only one argument?
  if #args == 1 and type(args) ~= 'table' then
    stop('Too few locale.merge() arguments.')
    end
    
  --used a table instead of multiple arguments...
  if #args == 1 and type(args) == 'table' then
    args = args[1]
    end

  --construct nested "localized-string" table.
  --base game does not permit more than 20 arguments per table.
  repeat
    local new_args = {}
    for i=1,#args,9 do
      local x = (#args - i + 1)
      table_insert(new_args,{ --merge blocks of up to 9 things at a time
        'liblocale.merge'..tostring((x < 9) and x or 9), --the length of the last block must be precise!
        args[i+0],args[i+1],args[i+2],
        args[i+3],args[i+4],args[i+5],
        args[i+6],args[i+7],args[i+8],
        })
      end
    args = new_args
    until #args == 1 --nest things into each other until there's only *one* master table left
  
  return args[1]
  end
Usage example:

Code: Select all

log(merge('One: ',game.create_profiler(),'Two: ',game.create_profiler()))
Edit 1,2,3: So, as noted in the next post this whole hack can work just fine without locale.cfg entries. Time to fix my code.
Last edited by eradicator on Thu Aug 29, 2019 5:28 pm, edited 4 times in total.
Author of: Belt Planner, Hand Crank Generator, Screenshot Maker, /sudo and more.
Mod support languages: 日本語, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.
orzelek
Smart Inserter
Smart Inserter
Posts: 3928
Joined: Fri Apr 03, 2015 10:20 am
Contact:

Re: LuaProfiler and logging

Post by orzelek »

A lot of hacking here... seems like lua ;)
Is there any actual way to log profiler time to log written to script-output?

Any way of allowing the profiler to change itself to string to be sent to logger would be pretty useful.
User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5211
Joined: Tue Jul 12, 2016 9:03 am
Contact:

Re: LuaProfiler and logging

Post by eradicator »

Omf. I'm feel really stupid now. Ofc i can just use...

Code: Select all

/c log{'','First: [',game.create_profiler(),'], Second: [',game.create_profiler(),']'}
>> First: [Elapsed: 0.018388ms], Second: [Elapsed: 0.030790ms]
@orzelek: game.write_file accepts localized strings, so it should work the same.
Author of: Belt Planner, Hand Crank Generator, Screenshot Maker, /sudo and more.
Mod support languages: 日本語, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.
orzelek
Smart Inserter
Smart Inserter
Posts: 3928
Joined: Fri Apr 03, 2015 10:20 am
Contact:

Re: LuaProfiler and logging

Post by orzelek »

eradicator wrote: Thu Aug 29, 2019 5:20 pm Omf. I'm feel really stupid now. Ofc i can just use...

Code: Select all

/c log{'','First: [',game.create_profiler(),'], Second: [',game.create_profiler(),']'}
>> First: [Elapsed: 0.018388ms], Second: [Elapsed: 0.030790ms]
@orzelek: game.write_file accepts localized strings, so it should work the same.
The thing is that it's wrapped into a debug object to cache strings and write up periodically. And it's a lua magic a bit for me (been in RSO for a long time before I took over). I guess I might need to make it go directly to write_file or write a debug method that accepts table and forwards it to write_file (if that makes sens in lua? I'm a c++/C# person :D).
User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5211
Joined: Tue Jul 12, 2016 9:03 am
Contact:

Re: LuaProfiler and logging

Post by eradicator »

orzelek wrote: Thu Aug 29, 2019 5:43 pm The thing is that it's wrapped into a debug object to cache strings and write up periodically. And it's a lua magic a bit for me (been in RSO for a long time before I took over).
I didn't even know you *took over* RSO from someone else :p.

LuaProfiler is always a table, never a string, so if it's working now (except for the __1__ string replacements) then it shouldn't be a problem. Otherwise you'll have to fix the mod code to handle localized strings (==tables) in that part. Feel free to post links to github or something of the problematic parts? (No promises...)

For references i updated my merger (brand new and untested) to use the empty string method instead of relying on locale entries. But it's not really nessecary if you're merging fewer than 20 string "parts". (The "twenty" is a weird engine limitation btw, that merge() circumvents by chopping large tables up into smaller nested tables.)

Code: Select all

/c
--[[merges an arbitrary number of stuff into a localized string without needing locale.cfg entries]]
function merge2(...)
  local args = {...}
  
  local function pack20(tbl)
    local r = {''}
    for i=0,#tbl,20 do
      local segment = {''}
      for j=1,20 do
        local elm = tbl[i+j]
        segment[#segment+1] = (type(elm)=='table' and elm.valid) and {'','[',elm,']'} or elm
        end
      r[#r+1] = segment
      end
    return r
    end

  --[[each level can contain the { _KEY_ ,plus,twenty,strings,or,tables}]]
  repeat args = pack20(args) until #args < 22
  return args
  end
Example:

Code: Select all

/c
local long = {}
for i=1,90 do table.insert(long,' '..tostring(i)..' ') end  
local test = merge2('one: ',game.create_profiler(),'2: ',{'item-name.iron-plate'},game.player,unpack(long))
game.print(test)
print(serpent.line(test))
Author of: Belt Planner, Hand Crank Generator, Screenshot Maker, /sudo and more.
Mod support languages: 日本語, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.
slippycheeze
Filter Inserter
Filter Inserter
Posts: 587
Joined: Sun Jun 09, 2019 10:40 pm
Contact:

Re: LuaProfiler and logging

Post by slippycheeze »

FWIW, I've used the "just write it please" localized string format {"", text_to_print} successfully. I don't see why it wouldn't work here, and since you can compose the second string with arbitrary lua string operations you should be able to just use .. or table.join (or is it string.join, I never remember) to build the second argument. If it doesn't just write them all, I don't think I ever tried.
Post Reply

Return to “Modding help”