1. Challenge: Build a Color-Coded Log Viewer for Phix/Euphoria (Inspired by chat.exw)
- Posted by xecronix 2 weeks ago
- 493 views
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 backgroundMessages 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?
2. Re: Challenge: Build a Color-Coded Log Viewer for Phix/Euphoria (Inspired by chat.exw)
- Posted by Icy_Viking 2 weeks ago
- 490 views
I thought Euphoria could only read functions from DLLs written in C?
3. Re: Challenge: Build a Color-Coded Log Viewer for Phix/Euphoria (Inspired by chat.exw)
- Posted by xecronix 2 weeks ago
- 488 views
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.
4. Re: Challenge: Build a Color-Coded Log Viewer for Phix/Euphoria (Inspired by chat.exw)
- Posted by petelomax 2 weeks ago
- 475 views
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.
5. Re: Challenge: Build a Color-Coded Log Viewer for Phix/Euphoria (Inspired by chat.exw)
- Posted by Icy_Viking 2 weeks ago
- 473 views
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.
6. Re: Challenge: Build a Color-Coded Log Viewer for Phix/Euphoria (Inspired by chat.exw)
- Posted by petelomax 2 weeks ago
- 469 views
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.
7. Re: Challenge: Build a Color-Coded Log Viewer for Phix/Euphoria (Inspired by chat.exw)
- Posted by xecronix 2 weeks ago
- 464 views
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!
8. Re: Challenge: Build a Color-Coded Log Viewer for Phix/Euphoria (Inspired by chat.exw)
- Posted by xecronix 2 weeks ago
- 460 views
... 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.
9. Re: Challenge: Build a Color-Coded Log Viewer for Phix/Euphoria (Inspired by chat.exw)
- Posted by euphoric (admin) 2 weeks ago
- 437 views
- The viewer receives log entries over TCP/IP.
Or MQTT.
10. Re: Challenge: Build a Color-Coded Log Viewer for Phix/Euphoria (Inspired by chat.exw)
- Posted by Icy_Viking 2 weeks ago
- 436 views
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]
11. Re: Challenge: Build a Color-Coded Log Viewer for Phix/Euphoria (Inspired by chat.exw)
- Posted by xecronix 2 weeks ago
- 426 views
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.
12. Re: Challenge: Build a Color-Coded Log Viewer for Phix/Euphoria (Inspired by chat.exw)
- Posted by jmduro 2 weeks ago
- 399 views
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
13. Re: Challenge: Build a Color-Coded Log Viewer for Phix/Euphoria (Inspired by chat.exw)
- Posted by xecronix 2 weeks ago
- 396 views
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.
- try and find someone to do a code review.
- write more tests. So far I have 3 passing tests. Probably a little weak to be honest.
- export the code as a dll/so. At the moment it's just a lib. (called units in pascal)
- make a Euphoria wrapper for the dll.
- if Phix wraps up differently, make a wrapper for that too.
- get this up on github.
14. Re: Challenge: Build a Color-Coded Log Viewer for Phix/Euphoria (Inspired by chat.exw)
- Posted by xecronix 2 weeks ago
- 388 views
Here is a program that converts a log in a colored HTML file. ... Jean-Marc
Looks great, awesome. Thanks.
15. Re: Challenge: Build a Color-Coded Log Viewer for Phix/Euphoria (Inspired by chat.exw)
- Posted by xecronix 2 weeks ago
- 391 views
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.
16. Re: Challenge: Build a Color-Coded Log Viewer for Phix/Euphoria (Inspired by chat.exw)
- Posted by Icy_Viking 2 weeks ago
- 383 views
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.
17. Re: Challenge: Build a Color-Coded Log Viewer for Phix/Euphoria (Inspired by chat.exw)
- Posted by xecronix 1 week ago
- 373 views
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.
18. Re: Challenge: Build a Color-Coded Log Viewer for Phix/Euphoria (Inspired by chat.exw)
- Posted by xecronix 1 week ago
- 361 views
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:
- Switch to UDP.
- Async calls in the client with very fast timeouts (50 or maybe 100 ms).
- Less than real-time log viewing.
- Multiple viewer retries until the logger takes a break from chatter.
- 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.
19. Re: Challenge: Build a Color-Coded Log Viewer for Phix/Euphoria (Inspired by chat.exw)
- Posted by xecronix 1 week ago
- 327 views
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.
20. Re: Challenge: Build a Color-Coded Log Viewer for Phix/Euphoria (Inspired by chat.exw)
- Posted by petelomax 1 week ago
- 325 views
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).
21. Re: Challenge: Build a Color-Coded Log Viewer for Phix/Euphoria (Inspired by chat.exw)
- Posted by euphoric (admin) 1 week ago
- 302 views
Mini Update...
That sounds awesome! Well done!
22. Re: Challenge: Build a Color-Coded Log Viewer for Phix/Euphoria (Inspired by chat.exw)
- Posted by xecronix 1 week ago
- 271 views
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
23. Re: Challenge: Build a Color-Coded Log Viewer for Phix/Euphoria (Inspired by chat.exw)
- Posted by Icy_Viking 1 week ago
- 257 views
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
24. Re: Challenge: Build a Color-Coded Log Viewer for Phix/Euphoria (Inspired by chat.exw)
- Posted by xecronix 1 week ago
- 226 views
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.
25. Re: Challenge: Build a Color-Coded Log Viewer for Phix/Euphoria (Inspired by chat.exw)
- Posted by Icy_Viking 1 week ago
- 226 views
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.
26. Re: Challenge: Build a Color-Coded Log Viewer for Phix/Euphoria (Inspired by chat.exw)
- Posted by ghaberek (admin) 1 week ago
- 205 views
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)
Example specifying level LOG_TRACE
-Greg