api-issue-tracker icon indicating copy to clipboard operation
api-issue-tracker copied to clipboard

Sketchup Ruby Console output to file

Open J-E-L opened this issue 6 years ago • 25 comments

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

J-E-L avatar Jul 24 '19 08:07 J-E-L

If I redirect “stdout” to a File, I do not get the “ERROR MESSAGES”

Have you tried to also redirect stderr?

thomthom avatar Jul 24 '19 15:07 thomthom

stderr do not get the „ERROR MESSAGE“

J-E-L avatar Jul 24 '19 15:07 J-E-L

What error message are you referring to?

thomthom avatar Jul 25 '19 08:07 thomthom

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 

J-E-L avatar Jul 25 '19 09:07 J-E-L

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.

thomthom avatar Jul 25 '19 10:07 thomthom

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.

thomthom avatar Jul 25 '19 10:07 thomthom

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.

J-E-L avatar Jul 25 '19 11:07 J-E-L

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'```

MSP-Greg avatar Jul 25 '19 12:07 MSP-Greg

Hello MSP-Greg Your Code did not work on Windows 10 and SketchUp 2019 Error: #<NoMethodError: undefined method `reopen' for #Sketchup::Console:0x000002b0c2aae4f0>

J-E-L avatar Jul 25 '19 15:07 J-E-L

@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...

MSP-Greg avatar Jul 25 '19 20:07 MSP-Greg

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

DanRathbun avatar Jul 26 '19 12:07 DanRathbun

@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 avatar Jul 26 '19 14:07 MSP-Greg

@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!

J-E-L avatar Jul 28 '19 16:07 J-E-L

@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...

MSP-Greg avatar Jul 28 '19 16:07 MSP-Greg

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.)

DanRathbun avatar Jul 28 '19 21:07 DanRathbun

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...

MSP-Greg avatar Jul 28 '19 21:07 MSP-Greg

The SketchUp Ruby Console has always been weird. I've always wanted to replace it with a better one.

DanRathbun avatar Jul 29 '19 13:07 DanRathbun

Some output in the Ruby Console might be printed directly instead of via stdout or stderr.

thomthom avatar Aug 16 '19 11:08 thomthom

It would be very good if the entire output goes over stdout and stderr. That would help me a lot.

J-E-L avatar Sep 04 '19 09:09 J-E-L

@thomthom Can we get this issue changed to a bug, as ALL output should go through $stdout and $stderr ?

DanRathbun avatar Aug 29 '20 02:08 DanRathbun

Logged as: SU-47093

sketchupbot avatar Sep 07 '20 06:09 sketchupbot

Thank you.

DanRathbun avatar Sep 07 '20 18:09 DanRathbun

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

kalpana-ghodeswar avatar May 16 '25 09:05 kalpana-ghodeswar

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

J-E-L avatar May 16 '25 14:05 J-E-L

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.

kalpana-ghodeswar avatar May 19 '25 09:05 kalpana-ghodeswar