Sketchup Ruby Console output to file
For connecting an IDE with Sketchup it would be help full to get all output from the Ruby Console into a file.
If I redirect “stdout” to a File, I do not get the “ERROR MESSAGES”
Example: (missing ERROR MESSAGES)
$stdout = File.open “C:\temp\my.log“, "a+:utf-8"
# Important ! Switch off Buffer
$stdout.sync = true
Example: (new feature) Switch on
SKETCHUP_CONSOLE.file = “C:\temp\my.log“ # Important ! Switch off Buffer
Switch off
SKETCHUP_CONSOLE.file = nil
If I redirect “stdout” to a File, I do not get the “ERROR MESSAGES”
Have you tried to also redirect stderr?
stderr do not get the „ERROR MESSAGE“
What error message are you referring to?
Here is an Example. Run the ruby script, appended below. You would see: stdout.log includes the String! stderr.log is empty! the error is only printed in the Sketchup ruby Console!
# ruby test start
testPath = "c:/temp"
outFile = File.new("#{testPath}/stdout.log", "w+")
errFile = File.new("#{testPath}/stderr.log", "w+")
outOrg = $stdout
errOrg = $stderr
$stdout = outFile
$stderr = errFile
begin
puts "Hello"
raise ArgumentError,"Test ERROR"
ensure
$stdout = outOrg
$stderr = errOrg
outFile.close
errFile.close
end
# ruby test end
I tried this in standalone Ruby and it doesn't work there either.
If you want to catch errors form your extension you could try something similar to how I collect errors for mine: https://github.com/thomthom/true-bend/blob/master/src/tt_truebend/command.rb
I add an exception handler in a custom UI::Command class that will catch any uncaught exceptions.
For connecting an IDE with Sketchup it would be help full to get all output from the Ruby Console into a file.
What IDE are you using? And why do you need to output errors to file when using an ide for debugging? The IDE should be able to let you inspect errors.
I use Netbeans. Netbeans starts as standard ruby script. (PseudoConsole) The PseudoConsole starts Sketchup with redirecting $stdout and $stderr to files. The PseudoConsole runs 3 Threads 1.) Read $stdout and print it in PseudoConsole 2.) Read $stderr and print it in PseudoConsole 3.) Read PseudoConsole.input and send it to Sketchup.
To get the Error messages to the file I use TracePoint but it do not get all ERROR yet.
Now I get nearly all output to Netbeans.
The advantage is: I can jump with a DoubbleClick on the Error Message to the Source Code Line where it happens.
It would we better and faster if I get the Error Message directly.
orig_out = $stdout.dup
orig_err = $stderr.dup
path = ENV['TMPDIR'] || ENV['TEMPDIR']
File.open("#{path}/stdout.log", mode: 'w+') { |f| $stdout.reopen f }
File.open("#{path}/stderr.log", mode: 'w+') { |f| $stderr.reopen f }
puts 'Hello from puts'
warn 'Hello from warn'
$stdout = orig_out
$stderr = orig_err
puts 'stdout works'
warn 'stderr works'```
Hello MSP-Greg Your Code did not work on Windows 10 and SketchUp 2019 Error: #<NoMethodError: undefined method `reopen' for #Sketchup::Console:0x000002b0c2aae4f0>
@SoapSkinBubble
My bad. Sorry. I saw the mention of stand-alone Ruby, made a few changes, and kind of forgot that SKETCHUP_CONSOLE only has a method or two in common with IO...
Just for reference, I asked how to send STDIO to an IDE in forum post ... https://forums.sketchup.com/t/how-to-send-console-output-to-debugger/77659
... but most discussion was in a thread of the SU Debugger GitHub project ... https://github.com/SketchUp/sketchup-ruby-debugger/issues/19
@SoapSkinBubble
Again, sorry for the previous post. Try the following:
# frozen_string_literal: true
$orig_out, $stdout = $stdout, STDOUT.dup
$orig_err, $stderr = $stderr, STDERR.dup
path = ENV['TMPDIR'] || ENV['TEMPDIR']
File.open("#{path}/stdout.log", mode: 'w+') { |f| $stdout.reopen f }
File.open("#{path}/stderr.log", mode: 'w+') { |f| $stderr.reopen f }
puts "[#{Time.now}] Hello from puts"
warn "[#{Time.now}] Hello from warn"
$stdout.close
$stderr.close
$stdout = $orig_out
$stderr = $orig_err
puts 'Restore SU Ruby console: stdout works'
warn 'Restore SU Ruby console: stderr works'
@MSP-Greg Sorry but you misunderstand my Problem. Writing to $stdout and $ stderr is working fine but if an error occurs, the Error Message is not written to one of the Files!
@SoapSkinBubble
I posted something in the forum with an attached file. See:
https://forums.sketchup.com/t/redirect-ruby-console-to-file-s-example/99790
I required it in a plugin and set SU_IO.file :err, which routes stderr to a file.
Normally when I load the plugin, a bunch of warnings ('warning: File.exists? is a deprecated name') appear in the console. With the SU_IO.file :err command in the plugin, the warnings do not appear in the console, but are in the file.
This seems to show that stderr is routed to a file, at least for loaded Ruby code.
I did notice that if you use the Ruby console and enter something that generates an error, it appears in the Ruby console... Not sure about that...
This seems to show that stderr is routed to a file, at least for loaded Ruby code.
I think some of the API exception code writes to $stdout and not $stderr (if memory serves. It seems this has been a complaint in the past.)
Since my code never has errors, I just used the warnings that appear in the Ruby console on SU start. Ok, just kidding.
I think some of the API exception code writes to $stdout and not $stderr
Could be. Kind of odd, because the standard Ruby C calls are build with errors going to stderr. Then again, some of the API c code could be quite old...
But, what I meant above is that if one uses the code to route both stdout & stderr to file(s), and then types some nonsense into the console like t = nil + 5, the error info appears in the console.
But, I did that, then triggered something in my plugin UI that writes with warn commands, and the warn string still went to the file. So I don't know...
The SketchUp Ruby Console has always been weird. I've always wanted to replace it with a better one.
Some output in the Ruby Console might be printed directly instead of via stdout or stderr.
It would be very good if the entire output goes over stdout and stderr. That would help me a lot.
@thomthom Can we get this issue changed to a bug, as ALL output should go through $stdout and $stderr ?
Logged as: SU-47093
Thank you.
Hi J-E-L,
I've been reviewing old bugs and attempted to reproduce this one. It works fine for me on SU2023.1, SU2024.0, and SU2025.0. If it's also working for you, can we proceed to close this issue?
Thank you Kalpana
Run the attached Ruby code.
$stdout contains text and $stderr is empty because the error is only written to the Ruby console.
path = File.dirname(__FILE__)
system "explorer \"#{path.gsub(/\//, "\\")}\""
stdout_file = File.join(path, "stdout.txt")
stderr_file = File.join(path, "stderr.txt")
$stdout = File.open stdout_file, "a+:utf-8"
$stderr = File.open stderr_file, "a+:utf-8"
$stdout.sync = true
$stderr.sync = true
puts "Start Test"
begin
raise ArgumentError, "Argument Error called"
end
Hi J-E-L
Yes I can reproduce it using the above code using versions SU2023.0, SU2024.0 and SU2025.0. I will keep this open and hopefully we will be able to fix this soon. Thanks for the feedback.