Como faço para prefixar informações para STDERR quando um método gera stderr?
Pergunta
Existe alguma maneira eu posso pegar quando um método gera uma gravação para STDERR? Estou tentando pré-PEND algumas informações com cada gravação STDERR.
Digamos que o nosso método é:
parser.thatGeneratesSTDERR();
que vai gerar algo como
linha 37:29 alternativa não viável em caráter 'a'
posso simplesmente envolvê-la com algo que chama a stderr a ser escrito e pré-PEND alguns Informações por isso vai ficar assim em vez disso:
arquivo: mybadfile.txt - line 37:29 alternativa não viável em caráter 'a'
Eu sei que eu provavelmente poderia cavar através do código real que faz a escrita STDERR mas eu realmente não quero fazer isso -. Eu prefiro só embrulhar algum código em torno deste método em vez
Gostaria de salientar que este método nem sempre gera STDERR - a razão que eu estou tentando pegá-los é que ele não deve ser gerar qualquer STDERR - mas uma vez que este é chamado em algumas arquivos (acima de 40) Eu nunca sei qual arquivo está gerando a mensagem de erro -. ele leva uma eternidade para encontrar
Atualizar assim yeh, podemos mudar a nossa STDERR - Eu estava esquecendo que eu preciso para substituir o meu println no meu novo STDERR ... aqui está o código relevante:
public static String errfile = "";
static {
final PrintStream currentErr = System.err;
PrintStream newErr = new PrintStream(currentErr)
{
public void println(String string) {
print("File: " + errfile + " --");
print(string);
super.println();
}
};
System.setErr(newErr);
}
, em seguida, para cada arquivo que eu estou testando tudo que tenho a fazer é mudar errfile ao nome do arquivo e minha saída sai esperado ...
muito obrigado!
Solução
Eu não tenho certeza se isso vai funcionar, dada a forma como System.setErr funciona.
Gostaria de criar uma nova classe que estende fluxo de impressão e substitui os métodos para preceder o seu comentário. Em seguida, defina o fluxo de erro para o seu novo PrintStream. Não chame System.err.printxxx a partir desta nova classe.
ex ...
class PrependPrintStream extends PrintStream {
PrependPrintStream(PrintStream ps, String pre){...}
...
public void print(boolean b) {
super.print(this.pre);
super.print(b);
}
...
Eu olhei para PrintStream impl do sol, e parece que tudo delegado printxxx para write (String) que é privado, em vez de protegido. Eu acho que você pode copiar / colar o código.
EDIT ::
A muito melhor solução é usar o log em vez de System.err. Isso permite que você desligar e ligar as suas declarações e permite que você crie um manipulador de erro personalizado. O manipulador específico poderia preceder a declaração que você deseja para a cadeia antes de imprimir para System.err. Isto também tem a vantagem de que apenas as declarações que usam o seu logger específico teria o texto prepended e outras chamadas para System.err não iria.
Outras dicas
Parece que você provavelmente vai querer olhar para Aspect Oriented Programming (AOP). Usando AOP, você pode criar um proxy para o analisador que você está chamando. Antes da thatGeneratesSTDERR chamada de método () você pode tê-lo invocação de você ligar. Desde a sua chamada você pode produzir as informações que deseja.
Note que pode demorar um pouco de leitura para entender como AOP funciona.
AspectJ - http://www.eclipse.org/aspectj/
AOP Alliance - http://sourceforge.net/projects/aopalliance
Você pode usar System.setErr para redirecionamento stderr para o seu próprio PrintStream.