1. Challenge: Build a Color-Coded Log Viewer for Phix/Euphoria (Inspired by chat.exw)

Challenge: Build a Color-Coded Log Viewer for Euphoria (Inspired by chat.exw)

Hi all,

I am issuing a small but meaningful challenge to the Euphoria/Phix community: Build a color-coded log viewer using IUP, inspired by Pete Lomax's chat.exw.

This is not just a toy idea. It is a genuinely useful debugging tool that could make Euphoria development smoother and more modern.

Specs

  • The viewer receives log entries over TCP/IP.
  • It displays messages in a scrollable panel or list area.
  • Each message affects the background color of all subsequent output, based on log level:

  ERROR:   -> light pink background   
  WARNING: -> yellow background   
  INFO:    -> green background   
  DEBUG:   -> white background   
  VERBOSE: -> white background 
Messages must start with the log level prefix (such as ERROR:). The background color remains in effect until a new prefix is seen.

  • The viewer does not edit log entries. It simply displays them in real-time (or in buffered batches if preferred).

My Role (xecronix / Ronald)

I will modify the following `logger.e` module to optionally write to a TCP/IP socket instead of a log file. This will allow the viewer to receive logs live, without requiring file polling or tailing.

Here is the original version of the logger:

-- logger.e 
-- File: lib/utils/logger.e 
 
include ../shared/constants.e 
include builtins/timedate.e 
 
global enum SILENT, ERR, INFO, DEBUG, TRACE, VERBOSE 
 
integer log_level = VERBOSE 
sequence log_file = "bzscript.log" 
integer log_handle = -1 
 
global procedure init_logger() 
    if not file_exists(log_file) then 
        log_handle = open(log_file, "w") 
    else 
        log_handle = open(log_file, "a") 
    end if 
    if log_handle = -1 then 
        puts(1, "[logger] Failed to open log file.\n") 
        abort(1) 
    end if 
end procedure 
 
global procedure close_logger() 
    if log_handle != -1 then 
        close(log_handle) 
        log_handle = -1 
    end if 
end procedure 
 
procedure log_line(sequence level, sequence msg) 
    sequence td = format_timedate(date(), "YYYY-MM-DD HH:mm:ss") 
    printf(log_handle, "[%s] [%s] %s\n", {td, level, msg}) 
end procedure 
 
procedure log_info(sequence msg) 
    log_line("info", msg) 
end procedure 
 
procedure log_debug(sequence msg) 
    log_line("debug", msg) 
end procedure 
 
procedure log_trace(sequence msg) 
    log_line("trace", msg) 
end procedure 
 
procedure log_error(sequence msg) 
    log_line("error", msg) 
end procedure 
 
procedure log_verbose(sequence msg) 
    log_line("verbose", msg) 
end procedure 
 
global procedure logger(integer level, sequence msg) 
    if log_handle = -1 then 
        init_logger() 
    end if 
    if level <= log_level then 
        if level = SILENT then 
            -- do nothing 
        elsif level = ERR then 
            log_error(msg) 
        elsif level = INFO then 
            log_info(msg) 
        elsif level = DEBUG then 
            log_debug(msg) 
        elsif level = TRACE then 
            log_trace(msg) 
        elsif level = VERBOSE then 
            log_verbose(msg) 
        else 
            log_error("**INVALID LOGGER TYPE**") 
            log_error(msg) 
        end if 
    end if 
end procedure 

Why This Matters

  • Euphoria has always been about simplicity and power. A simple real-time log viewer supports both goals.
  • If no one takes this on, I will write it in FreePascal, create a dll/so, and wrap it for Euphoria.
  • But I would rather see someone here step up and keep this kind of tooling native to the language.

Imagine a custom view of complex data while stepping thru code in the trace program/debugger.
Imagine a custom view of test results simply by logging.

Who's in?

Ronald Weidner

new topic     » topic index » view message » categorize

2. Re: Challenge: Build a Color-Coded Log Viewer for Phix/Euphoria (Inspired by chat.exw)

I thought Euphoria could only read functions from DLLs written in C?

new topic     » goto parent     » topic index » view message » categorize

3. Re: Challenge: Build a Color-Coded Log Viewer for Phix/Euphoria (Inspired by chat.exw)

I'll test that and let you know. But, that would be surprising to me. I can imagine cpp name mangling might be an issue? Maybe? Possibly OOP in general could be an issue? I wrote a tutorial on this a few years ago. I'll reuse that but write the dll in FreePascal to see what happens.

new topic     » goto parent     » topic index » view message » categorize

4. Re: Challenge: Build a Color-Coded Log Viewer for Phix/Euphoria (Inspired by chat.exw)

Sadly, you can't have it yet, but when(/if) I release 1.0.6 that will be ridiculously dirt-simple.
Here's an existing (non-runnable-by-you-lot) demo that shows three lines, middle one in red italic:

-- demo\theGUI\gList.exw 
include theGUI.e 
 
sequence data = {"one",{{"too",TG_RED,TG_ITALIC}},"three"} 
integer maxlen = largest(apply(data,length),return_index:=true) 
 
function get_data(integer idx) 
    if idx=0 then return length(data) end if 
    if idx=-1 then return maxlen end if 
    return data[idx] 
end function 
 
gdx list = gList(get_data,`FONT="Consolas, 12"`), 
     dlg = gDialog(list,"gList",`SIZE=240x80`) 
gSetAttribute(list,"BGCLR",TG_LIGHT_PARCHMENT) 
gShow(dlg) 
gMainLoop() 

The ",TG_ITALIC" can just be deleted, and the "TG_RED" replaced with "{TG_RED,TG_BLUE}" (or hex codes) to specify both foreground and background colours.
There is a not-yet-implemented SHOWLINE(/LASTLINE) attribute it would need, unless you'd accept last-first order or most recent messages not being visible.
Otherwise all it would need is to append data with new messages, each with whatever [multi-fragment] colouring it wants, bump maxlen if rqd, and a gRedraw() call.

I've been working on this for quite a while now, and it's getting there, but it's certainly been a good old fashioned slog, and the finishing line is still "maybe this year"...

PS I meant the GUI part would be trivial, I wasn't thinking about the TCP/IP part.

new topic     » goto parent     » topic index » view message » categorize

5. Re: Challenge: Build a Color-Coded Log Viewer for Phix/Euphoria (Inspired by chat.exw)

xecronix said...

I'll test that and let you know. But, that would be surprising to me. I can imagine cpp name mangling might be an issue? Maybe? Possibly OOP in general could be an issue? I wrote a tutorial on this a few years ago. I'll reuse that but write the dll in FreePascal to see what happens.

I think the CPP name mangling would be an issue, I assume it would also be an issue with other programming languages. I guess it might be possible with work-arounds or renaming/rewording the function names mangling due to OOP.

new topic     » goto parent     » topic index » view message » categorize

6. Re: Challenge: Build a Color-Coded Log Viewer for Phix/Euphoria (Inspired by chat.exw)

Icy_Viking said...

I think the CPP name mangling would be an issue, I assume it would also be an issue with other programming languages. I guess it might be possible with work-arounds or renaming/rewording the function names mangling due to OOP.

See for instance this.

I merely suspect trying to do GUI stuff in a dll might cause problems, whereas I'm much more (~66.6%) confident that trying to do some gui stuff in the dll and some outside the dll will pretty soon make you wish you had never been born.

new topic     » goto parent     » topic index » view message » categorize

7. Re: Challenge: Build a Color-Coded Log Viewer for Phix/Euphoria (Inspired by chat.exw)

I tested this with a trivial example:

Pascal Code:

library hello_export; 
 
uses 
  Classes, SysUtils; 
 
{$H+} 
 
function say_hello(): PChar; 
begin 
  Result := 'Hello from FreePascal DLL!'; 
end; 
 
exports 
  say_hello; 
 
begin 
end. 
 

And the Euphoria that runs it:

include std/dll.e  
include std/machine.e  
include std/pretty.e  
include std/filesys.e  
 
sequence dll_name = "hello_export.dll" 
printf(1, "loading dll: %s\n", {dll_name}) 
atom lib = open_dll(dll_name)  
atom hello = define_c_func(lib, "say_hello", {}, C_POINTER) 
atom ptr = c_func(hello, {})  
sequence msg = peek_string(ptr) 
printf(1, "Returned from DLL: %s\n", {msg}) 

My only proof it works:

Owner@DESKTOP-VHI2MMV MINGW64 /c/dev/fpc_units/simple_dll 
$ eui hello_eu.ex 
loading dll: hello_export.dll 
Returned from DLL: Hello from FreePascal DLL! 

new topic     » goto parent     » topic index » view message » categorize

8. Re: Challenge: Build a Color-Coded Log Viewer for Phix/Euphoria (Inspired by chat.exw)

petelomax said...

... confident that trying to do some gui stuff in the dll and some outside the dll will pretty soon make you wish you had never been born.

Actually, I think you're right. But, the logger can be a dll. It would have the TCP/IP functionality needed. But, honestly that could be done in Euphoria too... either way.

As for the viewer. I think it might be enough to stack labels on a scrollable window. Instead of using a text area of some kind stack labels. Doing it this way might give someone control over background color per message. (Could it work? IDK. Maybe?)

If I write it, I'm using Lazarus and FreePascal. The exe speed and GUI is just too good to ignore. The entire program would be a single dll with just a few hooks for init start and stop. Where init exposes port to bind to and maybe few other little bits. Maybe an option to write to a file? And I'd try the stacking labels thing. Or.... Maybe HTML? I'll see if there's a widget for that.

new topic     » goto parent     » topic index » view message » categorize

9. Re: Challenge: Build a Color-Coded Log Viewer for Phix/Euphoria (Inspired by chat.exw)

xecronix said...
  • The viewer receives log entries over TCP/IP.

Or MQTT.

new topic     » goto parent     » topic index » view message » categorize

10. Re: Challenge: Build a Color-Coded Log Viewer for Phix/Euphoria (Inspired by chat.exw)

xecronix said...

I tested this with a trivial example:

Pascal Code:

library hello_export; 
 
uses 
  Classes, SysUtils; 
 
{$H+} 
 
function say_hello(): PChar; 
begin 
  Result := 'Hello from FreePascal DLL!'; 
end; 
 
exports 
  say_hello; 
 
begin 
end. 
 

And the Euphoria that runs it:

include std/dll.e  
include std/machine.e  
include std/pretty.e  
include std/filesys.e  
 
sequence dll_name = "hello_export.dll" 
printf(1, "loading dll: %s\n", {dll_name}) 
atom lib = open_dll(dll_name)  
atom hello = define_c_func(lib, "say_hello", {}, C_POINTER) 
atom ptr = c_func(hello, {})  
sequence msg = peek_string(ptr) 
printf(1, "Returned from DLL: %s\n", {msg}) 

My only proof it works:

Owner@DESKTOP-VHI2MMV MINGW64 /c/dev/fpc_units/simple_dll 
$ eui hello_eu.ex 
loading dll: hello_export.dll 
Returned from DLL: Hello from FreePascal DLL! 

That's pretty cool. I guess as long as Euphoria can open and read the function from the DLL, it probably doesn't matter what language a library is written in.

Using FFI Euphoria may also be of use [https://github.com/ghaberek/libffi-euphoria]

new topic     » goto parent     » topic index » view message » categorize

11. Re: Challenge: Build a Color-Coded Log Viewer for Phix/Euphoria (Inspired by chat.exw)

Here is a mockup of what I had in mind. It's kind of a semi-functional mock-up. It does parse a log file, mark it up a little to html, and display it. Can it be done in Euphoria or Phix instead of FreePascal? Probably. I'm moving on to the actual logger now. Essentially, I'm going to rewrite the one I did in Euphoria/Phix and make it a dll. Then wrap the dll in Euphoria. Hopefully, the logger (not the viewer) will be done today or tomorrow. We'll see.

https://static.wixstatic.com/media/b076d7_fcf70799aead4a3db98f339fa9cf8dd3~mv2.png

new topic     » goto parent     » topic index » view message » categorize

12. Re: Challenge: Build a Color-Coded Log Viewer for Phix/Euphoria (Inspired by chat.exw)

Here is a program that converts a log in a colored HTML file.

include std/filesys.e 
include std/io.e 
include std/search.e 
 
sequence cmd = command_line() 
if length(cmd) < 3 then 
  puts(STDERR, "Syntax: html_log file\n") 
  abort(1) 
end if 
sequence log_file = cmd[3] 
 
integer f_out = open(filebase(log_file) & ".html", "w") 
puts(f_out, "<!DOCTYPE html>\n<html>\n<title>HTML Log</title>\n" & 
  "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n" & 
  "<link rel=\"stylesheet\" href=\"https://www.w3schools.com/w3css/5/w3.css\">\n<body>" 
) 
sequence lines = read_lines(log_file) 
if begins({#EF,#BB,#BF}, lines[1]) then  -- UTF-8 BOM 
  lines[1] = remove(lines[1], 1, 3) 
end if 
for i = 1 to length( lines ) label "main" do 
  if length(lines[i]) = 0 then continue end if 
  if begins("[verbose]", lines[i]) then 
    puts(f_out, "<div class=\"w3-container w3-light-grey\">\n") 
    puts(f_out, lines[i] & "\n") 
    puts(f_out, "</div>\n") 
  elsif begins("[debug]", lines[i]) then 
    puts(f_out, "<div class=\"w3-container w3-white\">\n") 
    puts(f_out, lines[i] & "\n") 
    puts(f_out, "</div>\n") 
  elsif begins("[warning]", lines[i]) then 
    puts(f_out, "<div class=\"w3-container w3-pale-yellow\">\n") 
    puts(f_out, lines[i] & "\n") 
    puts(f_out, "</div>\n") 
  elsif begins("[error]", lines[i]) then 
    puts(f_out, "<div class=\"w3-container w3-pale-red\">\n") 
    puts(f_out, lines[i] & "\n") 
    puts(f_out, "</div>\n") 
  elsif begins("[info]", lines[i]) then 
    puts(f_out, "<div class=\"w3-container w3-pale-green\">\n") 
    puts(f_out, lines[i] & "\n") 
    puts(f_out, "</div>\n") 
  else 
    puts(f_out, lines[i] & "\n") 
  end if 
end for   
puts(f_out, "</body>\n</html>") 
close(f_out) 

Jean-Marc

new topic     » goto parent     » topic index » view message » categorize

13. Re: Challenge: Build a Color-Coded Log Viewer for Phix/Euphoria (Inspired by chat.exw)

I have completed the happy path for the logger. The Pascal code is shown below. If you're working on a live stream log viewer, the important bits to note about the logger are:

This is the message format. Msg can have newlines. So I made an <EOM> End Of Message delimiter. It's configurable. (see config file below)

FullMsg := '[' + LevelStr + '] [' + FormatTimestamp + '] ' + Msg;  

This is how data moves across the wire. LineEnding is configured to be platform specific.

      Data := Payload + LineEnding + MessageTerminator + LineEnding; 
      Sock.SendString(Data);   

I tightened this up a little bit. There are more details, but this shows the log levels and their strings in the correct order.

  case ALevel of 
    llSilent:      ; // no output 
    llError:       LogLine('ERROR', Msg); 
    llWarning:     LogLine('WARNING', Msg); 
    llInfo:        LogLine('INFO', Msg); 
    llDebug:       LogLine('DEBUG', Msg); 
    llVerbose:     LogLine('VERBOSE', Msg); 
  end;  

This is an example config file.

[viewer] 
in_log_file=bzlog-sample.log 
port=9595 
out_log_file=viewer-output.log 
socket_timeout_ms=30000 
message_terminator=MAGIC$sdfgsdfgsdfgEND_OF_MESSAGE 
 
[client] 
viewer_ip=127.0.0.1 
viewer_port=9595 
message_terminator=MAGIC$sdfgsdfgsdfgEND_OF_MESSAGE 
fallback_log_file=bzlog-sample.log 

Full Pascal source. This is subject to change, but it should be close enough for you if you're working on a live log viewer.

unit bzlogger; 
 
{$mode objfpc}{$H+} 
 
interface 
 
uses 
  Classes, SysUtils; 
 
type 
  TLogLevel = (llSilent, llError, llWarning, llInfo, llDebug, llVerbose); 
 
procedure InitLogger(const AConfigFile: string = 'bzlog.conf'); 
procedure CloseLogger; 
procedure Logger(ALevel: TLogLevel; const Msg: string); 
procedure SetLogLevel(ALevel: TLogLevel); 
 
const 
  SILENT     = llSilent; 
  ERROR      = llError; 
  WARNING    = llWarning; 
  INFO       = llInfo; 
  DEBUG      = llDebug; 
  VERBOSE    = llVerbose; 
 
implementation 
 
uses 
  IniFiles, blcksock, synautil; 
 
var 
  LogFile: TextFile; 
  LogFileOpen: Boolean = False; 
  LogFileName: string = 'bzscript.log'; 
  CurrentLogLevel: TLogLevel = llVerbose; 
 
  ViewerIP: string = '127.0.0.1'; 
  ViewerPort: Word = 9595; 
  MessageTerminator: string = '<EOL>'; 
  FallbackLogFile: string = 'bzscript.log'; 
  ConfLoaded: Boolean = False; 
 
procedure LoadConfig(const AConfigFile: string); 
var 
  Ini: TIniFile; 
begin 
  Ini := TIniFile.Create(AConfigFile); 
  try 
    ViewerIP         := Ini.ReadString('client', 'viewer_ip', '127.0.0.1'); 
    ViewerPort       := Ini.ReadInteger('client', 'viewer_port', 9595); 
    MessageTerminator:= Ini.ReadString('client', 'message_terminator', '<EOM>'); 
    FallbackLogFile  := Ini.ReadString('client', 'fallback_log_file', 'bzscript.log'); 
  finally 
    Ini.Free; 
  end; 
  ConfLoaded := True; 
end; 
 
procedure InitLogger(const AConfigFile: string); 
begin 
  LoadConfig(AConfigFile); 
  LogFileName := FallbackLogFile; 
  AssignFile(LogFile, LogFileName); 
  if FileExists(LogFileName) then 
    Append(LogFile) 
  else 
    Rewrite(LogFile); 
  LogFileOpen := True; 
end; 
 
procedure CloseLogger; 
begin 
  if LogFileOpen then 
  begin 
    CloseFile(LogFile); 
    LogFileOpen := False; 
  end; 
end; 
 
procedure SetLogLevel(ALevel: TLogLevel); 
begin 
  CurrentLogLevel := ALevel; 
end; 
 
function FormatTimestamp: string; 
begin 
  Result := FormatDateTime('yyyy-mm-dd hh:nn:ss', Now); 
end; 
 
procedure WriteToFile(const LevelStr, Msg: string); 
begin 
  if not LogFileOpen then 
    InitLogger(''); 
 
  WriteLn(LogFile, '[' + LevelStr + '] [' + FormatTimestamp + '] ' + Msg); 
  Flush(LogFile); 
end; 
 
function SendLogOverTcp(const Payload: string): Boolean; 
var 
  Sock: TTCPBlockSocket; 
  Data: string; 
begin 
  Result := False; 
  Sock := TTCPBlockSocket.Create; 
  try 
    Sock.Connect(ViewerIP, IntToStr(ViewerPort)); 
    if Sock.LastError = 0 then 
    begin 
      Data := Payload + LineEnding + MessageTerminator + LineEnding; 
      Sock.SendString(Data); 
      if Sock.LastError = 0 then 
        Result := True 
      else 
        WriteToFile('TCP_FAIL', 'Send error: ' + Sock.LastErrorDesc); 
    end 
    else 
      WriteToFile('TCP_FAIL', 'Connect error: ' + Sock.LastErrorDesc); 
  finally 
    Sock.Free; 
  end; 
end; 
 
procedure LogLine(const LevelStr, Msg: string); 
var 
  FullMsg: string; 
begin 
  FullMsg := '[' + LevelStr + '] [' + FormatTimestamp + '] ' + Msg; 
 
  if not ConfLoaded then 
    InitLogger(''); 
 
  if not SendLogOverTcp(FullMsg) then 
    WriteToFile(LevelStr, Msg); 
end; 
 
procedure Logger(ALevel: TLogLevel; const Msg: string); 
begin 
  if ALevel > CurrentLogLevel then 
    Exit; 
 
  case ALevel of 
    llSilent:      ; // no output 
    llError:       LogLine('ERROR', Msg); 
    llWarning:     LogLine('WARNING', Msg); 
    llInfo:        LogLine('INFO', Msg); 
    llDebug:       LogLine('DEBUG', Msg); 
    llVerbose:     LogLine('VERBOSE', Msg); 
  end; 
end; 
 
end. 
 

My next steps.

  1. try and find someone to do a code review.
  2. write more tests. So far I have 3 passing tests. Probably a little weak to be honest.
  3. export the code as a dll/so. At the moment it's just a lib. (called units in pascal)
  4. make a Euphoria wrapper for the dll.
  5. if Phix wraps up differently, make a wrapper for that too.
  6. get this up on github.
new topic     » goto parent     » topic index » view message » categorize

14. Re: Challenge: Build a Color-Coded Log Viewer for Phix/Euphoria (Inspired by chat.exw)

jmduro said...

Here is a program that converts a log in a colored HTML file. ... Jean-Marc

Looks great, awesome. Thanks.

new topic     » goto parent     » topic index » view message » categorize

15. Re: Challenge: Build a Color-Coded Log Viewer for Phix/Euphoria (Inspired by chat.exw)

well... as it turns out... there are differences between Euphoria and Phix that matter in this context. Phix can only open 32 bit dlls and Euphoria can only open 64 bit dlls. (on my machine) I'm not sure if ffi helps or not, but, I got some reading to do, it seems. Darn.

new topic     » goto parent     » topic index » view message » categorize

16. Re: Challenge: Build a Color-Coded Log Viewer for Phix/Euphoria (Inspired by chat.exw)

xecronix said...

well... as it turns out... there are differences between Euphoria and Phix that matter in this context. Phix can only open 32 bit dlls and Euphoria can only open 64 bit dlls. (on my machine) I'm not sure if ffi helps or not, but, I got some reading to do, it seems. Darn.

Euphoria has both a 32-bits version and a 64-bits version. You can see from here [https://openeuphoria.org/wiki/view/DownloadEuphoria.wc] I have both 32-bits and 64-bits Eu installed on my machine.

I can probably help with wrapping as that's what I've mostly been doing with Euphoria these days.

new topic     » goto parent     » topic index » view message » categorize

17. Re: Challenge: Build a Color-Coded Log Viewer for Phix/Euphoria (Inspired by chat.exw)

Icy_Viking said...

I can probably help with wrapping as that's what I've mostly been doing with Euphoria these days.

Awesome. Thank you for the offer. I'll put the code and docs on github tomorrow then ping this thread. I guess I'll put binaries there too.

new topic     » goto parent     » topic index » view message » categorize

18. Re: Challenge: Build a Color-Coded Log Viewer for Phix/Euphoria (Inspired by chat.exw)

Update... There are more edge cases than I expected. Testing is slow going as a result. Progress continues. But... slower. All of the edge cases revolve around bringing the viewer online while the client is running. (simulating attaching to an already running process) Or the opposite, taking the viewer down while the logging client is running. It might be better to write it native to Phix/Euphoria. The viewer concept seems to be working, though. Yay!

What works well is if you already have the viewer running before starting logs. Or, if you never start the viewer while logs are being written. Anything in between is luck and timing.

The trick to solving this will likely be one of these things:

  1. Switch to UDP.
  2. Async calls in the client with very fast timeouts (50 or maybe 100 ms).
  3. Less than real-time log viewing.
  4. Multiple viewer retries until the logger takes a break from chatter.
  5. Live with the limitation and document start/stop the viewer before logging starts.


UDP is a very fast and easy approach. It's perfect for this kind of app. But I have hopes that the viewer might be able to evolve into a remote debugger. UDP is not well suited for that.

Async also solves some of the problems, but it would need a logging dll for Euphoria... I think. Right now, such a dll is optional for Euphoria/Phix as the logger can be written natively. IIRC threads aren't possible in Euphoria. So async seems not likey. Phix does have threads... I think.

OK, that's my update.

new topic     » goto parent     » topic index » view message » categorize

19. Re: Challenge: Build a Color-Coded Log Viewer for Phix/Euphoria (Inspired by chat.exw)

Mini Update

I went the UDP route. Logging is blazing fast now, and none of the weird timing issues I had before are showing up. I added a limit to the size of a single log message: 8 KB max. Anything longer gets truncated. In practice, most of my log messages are between 50 and 300 bytes, so 8 KB should be more than enough.

I also built a log viewer. It's threaded and very responsive. It's a standalone .exe, not a DLL. It can handle 1,000 log messages up to 8 KB each in near real-time. If messages come in faster than every 200 ms, the viewer buffers up to 1,000 of them and renders them in batches every 200 ms. I'm working on a static-view mode next, for reviewing log files longer than 1,000 entries.

new topic     » goto parent     » topic index » view message » categorize

20. Re: Challenge: Build a Color-Coded Log Viewer for Phix/Euphoria (Inspired by chat.exw)

Icy_Viking said...
xecronix said...

Phix can only open 32 bit dlls and Euphoria can only open 64 bit dlls.

Euphoria has both a 32-bits version and a 64-bits version.

Oh yeah, I was going to say the other day when oven timer went off, so I went and had dinner and forgot.
Same deal for Phix. You may want to create a p64.exw:

format PE64 --GUI 
include p.exw 

then compile that (p -c p64) and you'll have both 32 and 64 bit to hand. You may want to uncomment the GUI, perhaps separately, to avoid the DOS box and/or have p.exe, pw.exe, p64.exe, and pw64.exe.
I've not yet found any good reason to shift/copy the 64-bit version out of C:\Program Files (x86)\Phix into C:\Program Files\Phix (and update|extend your PATH), but that's not to say there isn't one, though
I will just add that trying to have both on the same box with the exact same name(s) is unlikely to work well..

The one thing I've never done is find/package up 64-bit versions of LiteZip.dll and LiteUnzip.dll, I just noticed my sqlite3.dll looks a bit lonely too, and conversely but there's a good reason for it there is only a 64-bit version of primesieve.dll (which remains undocumented, except for the notes in builtins\primesieve.e and use in a rosettacode task or two).

new topic     » goto parent     » topic index » view message » categorize

21. Re: Challenge: Build a Color-Coded Log Viewer for Phix/Euphoria (Inspired by chat.exw)

xecronix said...

Mini Update...

That sounds awesome! Well done!

new topic     » goto parent     » topic index » view message » categorize

22. Re: Challenge: Build a Color-Coded Log Viewer for Phix/Euphoria (Inspired by chat.exw)

I've uploaded the logger project here:
https://github.com/xecronix/BzTelemetry

I also partly implemented a wrapper. (For Phix 32 bit)
https://github.com/xecronix/BzTelemetry/blob/main/example-wrappers/bzlog.e

This is what you need to know if you're going to write a wrapper
https://github.com/xecronix/BzTelemetry/blob/main/bzlogger_core/bzlogger_win_wrap.pas

And these are the exported names of the functions.
https://github.com/xecronix/BzTelemetry/blob/main/bzlogger_core/BzLoggerDLL.lpr

This is the pre-built 32 bit version of the dll
https://github.com/xecronix/BzTelemetry/blob/main/bzlogger_core/bzlogger_32.dll

This is the pre-built viewer (this development is active ATM)
https://github.com/xecronix/BzTelemetry/blob/main/logViewer/log_viewer.exe

new topic     » goto parent     » topic index » view message » categorize

23. Re: Challenge: Build a Color-Coded Log Viewer for Phix/Euphoria (Inspired by chat.exw)

Here is the Euphoria wrapper, based of the Pascal Win wrapper.

You can get the Euphoria FFI from here: [https://github.com/ghaberek/libffi-euphoria]

--Bzlogger Euphoria Wrapper 
--Written by Andy P. 
--Using FFI Euphoria wrapper 
--Using Euphoria 4.1.0 Beta 2 
 
--Note: FFI.e gives us C_STRING which wraps 'allocate_string' for us 
 
--Euphoria Wrapper based off of xecronix's Pascal bzlogger_win_wrap.pas 
 
--Note 2: DLL file must be in same folder/directory as bzlogger.e for it to load correctly 
 
include std/ffi.e 
include std/machine.e 
include std/os.e 
 
--Global vars 
public atom bzlog 
 
--Constants 
public constant LOG_SILENT = 0, 
			    LOG_ERROR = 1, 
			    LOG_WARN = 2, 
			    LOG_INFO = 3, 
			    LOG_DEBUG = 4, 
			    LOG_VERBOSE = 5 
 
--Load DLL/Shared library for various OS's 
ifdef WINDOWS then 
	bzlog = open_dll("bzlogger_32.dll") 
	elsifdef LINUX or FREEBSD then 
	bzlog = open_dll("libbzlogger_32.so") 
	elsifdef OSX then 
	bzlog = open_dll("libbzlogger_32.dylib") 
end ifdef 
 
--If can't load DLL, display error 
if bzlog = 0 then 
	puts(1,"Failed to load bzlogger_32!\n") 
	abort(0) 
end if 
 
--Wrap Functions 
 
public constant xInitLogger = define_c_proc(bzlog,"+init_logger",{C_STRING}), 
				xCloseLogger = define_c_proc(bzlog,"+close_logger",{}), 
				xLogger = define_c_proc(bzlog,"+logger",{C_INT,C_STRING}) 
 
public procedure InitLogger(sequence configFile) 
	c_proc(xInitLogger,{configFile}) 
end procedure 
 
public procedure CloseLogger() 
	c_proc(xCloseLogger,{}) 
end procedure 
 
public procedure Logger(atom alevel,sequence msg) 
	c_proc(xLogger,{alevel,msg}) 
end procedure 
 
public constant xSetLogLevel = define_c_proc(bzlog,"+set_log_level",{C_INT}), 
				xSetLogFileName = define_c_proc(bzlog,"+set_log_file_name",{C_STRING}), 
				xSetViewerIP = define_c_proc(bzlog,"+set_viewer_ip",{C_STRING}), 
				xSetViewerPort = define_c_proc(bzlog,"+set_viewer_port",{C_WORD}) 
				 
public procedure SetLogLevel(atom alevel) 
	c_proc(xSetLogLevel,{alevel}) 
end procedure 
 
public procedure SetLogFileName(sequence aFileName) 
	c_proc(xSetLogFileName,{aFileName}) 
end procedure 
 
public procedure SetViewerIP(sequence AIP) 
	c_proc(xSetViewerIP,{AIP}) 
end procedure 
 
public procedure SetViewerPort(atom aPort) 
	c_proc(xSetViewerPort,{aPort}) 
end procedure 
 
public constant xGetLogFileName = define_c_func(bzlog,"+get_log_file_name",{},C_STRING), 
				xGetLogLevel = define_c_func(bzlog,"+get_log_level",{},C_INT), 
				xGetViewerIP = define_c_func(bzlog,"+get_viewer_ip",{},C_STRING), 
				xGetViewerPort = define_c_func(bzlog,"+get_viewer_port",{},C_WORD), 
				xIsConfigLoaded = define_c_func(bzlog,"+is_config_loaded",{},C_BOOL) 
 
public function GetLogFileName() 
	return c_func(xGetLogFileName,{}) 
end function 
 
public function GetLogLevel() 
	return c_func(xGetLogLevel,{}) 
end function 
 
public function GetViewerIP() 
	return c_func(xGetViewerIP,{})	 
end function 
 
public function GetViewerPort() 
	return c_func(xGetViewerPort,{}) 
end function 
 
public function IsConfigLoaded() 
	return c_func(xIsConfigLoaded,{}) 
end function 
new topic     » goto parent     » topic index » view message » categorize

24. Re: Challenge: Build a Color-Coded Log Viewer for Phix/Euphoria (Inspired by chat.exw)

Awesome! Thanks. I'll test and commit. I'm a little concerned about the function names though. I exported them in snake case instead of camel case. So, we'll see if both are in the dll. IDK.

Thanks again.

new topic     » goto parent     » topic index » view message » categorize

25. Re: Challenge: Build a Color-Coded Log Viewer for Phix/Euphoria (Inspired by chat.exw)

xecronix said...

Awesome! Thanks. I'll test and commit. I'm a little concerned about the function names though. I exported them in snake case instead of camel case. So, we'll see if both are in the dll. IDK.

Thanks again.

Oh I was going off of the pascal wrapper file. Its an easy fix, I'll fix it real quick. Now they are in snake case. Euphoria reads the DLL function name how it is in the DLL. So if the function name is in snake case, you'll need the name inside the quotes "" to be in snake case. Anyways its been fixed.

new topic     » goto parent     » topic index » view message » categorize

26. Re: Challenge: Build a Color-Coded Log Viewer for Phix/Euphoria (Inspired by chat.exw)

FYI I wrote a color-coded logging library for Euphoria MVC that I intend to port into the release of Euphoria 4.2.

It uses call_stack() from the newer debug library to provide the call details for each entry. (This only works in the interpreter and is ifdef'd out when translated.)

Features include:

  • Logging levels: LOG_TRACE, LOG_DEBUG, LOG_INFO, LOG_WARN, LOG_ERROR, LOG_FATAL
  • Additional LOG_VERBOSE flag, useful for providing "short" and "long" output
  • Log level can be set via Euphoria defines, e.g. eui -D LOG_TRACE app.ex or eu.cfg
  • Automatically pretty-prints anything passed to "%s" format specifier
  • Custom colors for each log parameter: date, stack info, log text, etc.
  • Supports multiple logging targets, e.g set_log_output({STDERR,"app.log"})
  • Overwrite log files by specifying "!" at the start of file name (defaults to append)

There are no dependencies on anything else from Euphoria MVC so you can drop it directly into your application.

https://github.com/OpenEuphoria/euphoria-mvc/blob/master/include/mvc/logger.e

Example with default level (LOG_INFO)

https://i.imgur.com/TswbfIil.png

Example specifying level LOG_TRACE

https://i.imgur.com/BiDG79Pl.png

-Greg

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu