Use of SystemOutputInterceptor with different groovy versions

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Use of SystemOutputInterceptor with different groovy versions

Merlin Beedell

I also noted that the following code would work just fine in recent Groovy version, but not in older.  The idea is to intercept the stdout (System.out) so any output can be logged to a text file as well as to the console [really rather handy!].

 

import groovy.ui.SystemOutputInterceptor

dateString = new Date().format("yyyyMMMdd-HHmmss")

logOutput = new PrintWriter(new File("./","scriptLog_" + dateString +".log"))  //log into the current directory

myLoger = new SystemOutputInterceptor(

   {Integer i, String s -> logOutput << s; logOutput.flush(); true }

)

myLoger.start()

 

In older groovy versions, it seems that the Integer parameter is not passed to the closure (and the ‘start’ method is not required either):

 

myLoger = new SystemOutputInterceptor(

{Integer i, String s -> logOutput << s; logOutput.flush(); true }

)

myLoger.start()

 

But I can’t think how I can specify this code so it works for all versions of Groovy.  This is the error if it is wrong (here under Groovy 2.0.5):

 

Caught: groovy.lang.MissingMethodException: No signature of method: test$_run_closure2.doCall() is applicable for argument types: (java.lang.Integer, java.lang.String) values: [0,  Hello world]

Possible solutions: doCall(java.lang.String), findAll(), findAll()

 

It is as though I need to be able to provide two closure definitions – one with and one without the Integer parameter.

Any ideas?

 

Merlin

Reply | Threaded
Open this post in threaded view
|

Re: Use of SystemOutputInterceptor with different groovy versions

paulk_asert
I guess we regarded that class as somewhat internal when we made that change. You could use:

myLogger = new SystemOutputInterceptor({
  Object... args -> logOutput << args[-1]; logOutput.flush(); true
})

Cheers, Paul.


On Fri, Nov 10, 2017 at 4:15 AM, Merlin Beedell <[hidden email]> wrote:

I also noted that the following code would work just fine in recent Groovy version, but not in older.  The idea is to intercept the stdout (System.out) so any output can be logged to a text file as well as to the console [really rather handy!].

 

import groovy.ui.SystemOutputInterceptor

dateString = new Date().format("yyyyMMMdd-HHmmss")

logOutput = new PrintWriter(new File("./","scriptLog_" + dateString +".log"))  //log into the current directory

myLoger = new SystemOutputInterceptor(

   {Integer i, String s -> logOutput << s; logOutput.flush(); true }

)

myLoger.start()

 

In older groovy versions, it seems that the Integer parameter is not passed to the closure (and the ‘start’ method is not required either):

 

myLoger = new SystemOutputInterceptor(

{Integer i, String s -> logOutput << s; logOutput.flush(); true }

)

myLoger.start()

 

But I can’t think how I can specify this code so it works for all versions of Groovy.  This is the error if it is wrong (here under Groovy 2.0.5):

 

Caught: groovy.lang.MissingMethodException: No signature of method: test$_run_closure2.doCall() is applicable for argument types: (java.lang.Integer, java.lang.String) values: [0,  Hello world]

Possible solutions: doCall(java.lang.String), findAll(), findAll()

 

It is as though I need to be able to provide two closure definitions – one with and one without the Integer parameter.

Any ideas?

 

Merlin


Reply | Threaded
Open this post in threaded view
|

RE: Use of SystemOutputInterceptor with different groovy versions

Merlin Beedell

Perfect – that works a treat.  I thought I needed to overload the closure – specifying 2 closures, one with 1 parameter and another with 2. But I don’t think that is possible.  Your solution is simple and effective – and now I can see how to use varags too.

 

I use it an all my critical scripts, as it is so useful.  It replicates the ‘tee’ command in Linux.

We do not use many bash or bat scripts any more, just groovy scripts. And now they get logged to file and screen when they run without any fancy loggers.

 

I don’t know if [the apache groovy dev team] might modify the documentation accordingly for this (and any other class) to cater for different Groovy versions.

 

Merlin

 

From: Paul King [mailto:[hidden email]]
Sent: 10 November 2017 01:06
To: [hidden email]
Subject: Re: Use of SystemOutputInterceptor with different groovy versions

 

I guess we regarded that class as somewhat internal when we made that change. You could use:

 

myLogger = new SystemOutputInterceptor({

  Object... args -> logOutput << args[-1]; logOutput.flush(); true

})

 

Cheers, Paul.

 

 

On Fri, Nov 10, 2017 at 4:15 AM, Merlin Beedell <[hidden email]> wrote:

I also noted that the following code would work just fine in recent Groovy version, but not in older.  The idea is to intercept the stdout (System.out) so any output can be logged to a text file as well as to the console [really rather handy!].

 

import groovy.ui.SystemOutputInterceptor

dateString = new Date().format("yyyyMMMdd-HHmmss")

logOutput = new PrintWriter(new File("./","scriptLog_" + dateString +".log"))  //log into the current directory

myLoger = new SystemOutputInterceptor(

   {Integer i, String s -> logOutput << s; logOutput.flush(); true }

)

myLoger.start()

 

In older groovy versions, it seems that the Integer parameter is not passed to the closure (and the ‘start’ method is not required either):

 

myLoger = new SystemOutputInterceptor(

{Integer i, String s -> logOutput << s; logOutput.flush(); true }

)

myLoger.start()

 

But I can’t think how I can specify this code so it works for all versions of Groovy.  This is the error if it is wrong (here under Groovy 2.0.5):

 

Caught: groovy.lang.MissingMethodException: No signature of method: test$_run_closure2.doCall() is applicable for argument types: (java.lang.Integer, java.lang.String) values: [0,  Hello world]

Possible solutions: doCall(java.lang.String), findAll(), findAll()

 

It is as though I need to be able to provide two closure definitions – one with and one without the Integer parameter.

Any ideas?

 

Merlin