001/*
002 * jPOS Project [http://jpos.org]
003 * Copyright (C) 2000-2026 jPOS Software SRL
004 *
005 * This program is free software: you can redistribute it and/or modify
006 * it under the terms of the GNU Affero General Public License as
007 * published by the Free Software Foundation, either version 3 of the
008 * License, or (at your option) any later version.
009 *
010 * This program is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
013 * GNU Affero General Public License for more details.
014 *
015 * You should have received a copy of the GNU Affero General Public License
016 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
017 */
018
019package org.jpos.q2.cli;
020
021import org.jpos.q2.CLICommand;
022import org.jpos.q2.CLIContext;
023import org.jpos.util.LogEvent;
024import org.jpos.util.LogListener;
025import org.jpos.util.Logger;
026import org.jpos.util.NameRegistrar;
027
028import java.io.PrintStream;
029import java.util.Date;
030import java.util.Iterator;
031import java.util.Map;
032
033public class TAIL implements CLICommand, LogListener {
034    PrintStream p;
035    CLIContext cli;
036    boolean ansi;
037
038    public void exec(CLIContext cli, String[] args) throws Exception {
039        this.p = new PrintStream(cli.getReader().getTerminal().output());
040        this.cli = cli;
041        this.ansi = false; // cli.getReader().getTerminal().isAnsiSupported();
042        if (args.length == 1) {
043            usage(cli);
044            return;
045        }
046        for (int i = 1; i < args.length; i++) {
047            try {
048                Logger logger = (Logger) NameRegistrar.get("logger." + args[i]);
049                logger.addListener(this);
050            } catch (NameRegistrar.NotFoundException e) {
051                cli.println("Logger " + args[i] + " not found -- ignored.");
052            }
053        }
054        // cli.getReader().readCharacter(new char[]{'q', 'Q'});
055        cli.getReader().readLine();
056        for (int i = 1; i < args.length; i++) {
057            try {
058                Logger logger = (Logger) NameRegistrar.get("logger." + args[i]);
059                logger.removeListener(this);
060            } catch (NameRegistrar.NotFoundException ignored) {
061                // NOPMD OK to happen
062            }
063        }
064    }
065
066    public void usage(CLIContext cli) {
067        cli.println("Usage: tail [log-name] [log-name] ...");
068        showLoggers(cli);
069    }
070
071    public synchronized LogEvent log(LogEvent ev) {
072        if (p != null) {
073            Date d = new Date(System.currentTimeMillis());
074//            if (ansi)
075//                cli.getOutputStream().write(1); // BOLD
076            cli.println(
077              ev.getSource().getLogger().getName() +
078                ": " + ev.getRealm() + " " + d.toString() + "." + d.getTime() % 1000
079            );
080            ev.dump(p, " ");
081//            if (ansi)
082//                cli.getOutputStream().write(0); // OFF
083
084            p.flush();
085        }
086        return ev;
087    }
088
089    private void showLoggers(CLIContext cli) {
090        NameRegistrar nr = NameRegistrar.getInstance();
091        int maxw = 0;
092        Iterator iter = NameRegistrar.getAsMap().entrySet().iterator();
093        StringBuilder sb = new StringBuilder("available loggers:");
094        while (iter.hasNext()) {
095            Map.Entry entry = (Map.Entry) iter.next();
096            String key = (String) entry.getKey();
097            if (key.startsWith("logger.") && entry.getValue() instanceof Logger) {
098                sb.append(' ');
099                sb.append(key.substring(7));
100            }
101        }
102        cli.println(sb.toString());
103    }
104}
105