/** * Copyright (c) 2019 Red Hat, Inc. * This program and the accompanying materials are made * available under the terms of the Eclipse Public License 2.0 * which is available at: * * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 * * Contributors: * Red Hat, Inc. - initial API and implementation */ package org.eclipse.jkube.kit.build.service.docker.access.log; import lombok.Builder; import lombok.EqualsAndHashCode; import lombok.Getter; import org.eclipse.jkube.kit.build.service.docker.helper.Timestamp; import org.fusesource.jansi.Ansi; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.time.format.FormatStyle; import static org.fusesource.jansi.Ansi.Color.BLACK; import static org.fusesource.jansi.Ansi.Color.BLUE; import static org.fusesource.jansi.Ansi.Color.CYAN; import static org.fusesource.jansi.Ansi.Color.GREEN; import static org.fusesource.jansi.Ansi.Color.MAGENTA; import static org.fusesource.jansi.Ansi.Color.RED; import static org.fusesource.jansi.Ansi.Color.YELLOW; import static org.fusesource.jansi.Ansi.ansi; @Getter @EqualsAndHashCode public class LogOutputSpec { public static final LogOutputSpec DEFAULT = new LogOutputSpec("", YELLOW, false , null, null, true, true); private static final String DEFAULT_TIMESTAMP_PATTERN = "HH:mm:ss.SSS"; private final boolean useColor; private final boolean logStdout; private final boolean fgBright; private String prefix; private Ansi.Color color; private DateTimeFormatter timeFormatter; private String file; // Palette used for prefixing the log output private static final Ansi.Color[] COLOR_PALETTE = { YELLOW,CYAN,MAGENTA,GREEN,RED,BLUE }; private static int globalColorIdx = 0; @Builder(toBuilder = true) private LogOutputSpec( String prefix, Ansi.Color color, boolean fgBright, DateTimeFormatter timeFormatter, String file, boolean useColor, boolean logStdout) { this.prefix = prefix; this.color = color; this.fgBright = fgBright; this.timeFormatter = timeFormatter; this.file = file; this.useColor = useColor; this.logStdout = logStdout; } public boolean isUseColor() { return useColor && (getFile() == null || isLogStdout()); } public String getPrompt(boolean withColor,Timestamp timestamp) { return formatTimestamp(timestamp,withColor) + formatPrefix(prefix, withColor); } private String formatTimestamp(Timestamp timestamp,boolean withColor) { if (timeFormatter == null) { return ""; } DateTimeFormatter formatter = DateTimeFormatter.ofPattern(DEFAULT_TIMESTAMP_PATTERN); LocalDateTime localDateTime = LocalDateTime.from(formatter.parse(timestamp.toString())); return (withColor ? ansi().fgBright(BLACK).a(localDateTime).reset().toString() : localDateTime) + " "; } private String formatPrefix(String prefix, boolean withColor) { if (withColor) { Ansi ansi = ansi(); if (fgBright) { ansi.fgBright(color); } else { ansi.fg(color); } return ansi.a(prefix).reset().toString(); } else { return prefix; } } public static class LogOutputSpecBuilder { public LogOutputSpecBuilder colorString(String color) { return colorString(color, false); } public LogOutputSpecBuilder colorString(String color, boolean fgBright) { if (color == null) { this.color = COLOR_PALETTE[globalColorIdx++ % COLOR_PALETTE.length]; } else { try { this.color = Ansi.Color.valueOf(color.toUpperCase()); this.fgBright = fgBright; } catch (IllegalArgumentException exp) { throw new IllegalArgumentException( "Invalid color '" + color + "'. Color must be one of YELLOW, CYAN, MAGENTA, GREEN, RED, BLUE or BLACK"); } } return this; } public LogOutputSpecBuilder timeFormatterString(String formatOrConstant) { if (formatOrConstant == null || formatOrConstant.equalsIgnoreCase("NONE") || formatOrConstant.equalsIgnoreCase("FALSE")) { timeFormatter = null; } else if (formatOrConstant.length() == 0 || formatOrConstant.equalsIgnoreCase("DEFAULT")) { timeFormatter = DateTimeFormatter.ofPattern(DEFAULT_TIMESTAMP_PATTERN); } else if (formatOrConstant.equalsIgnoreCase("ISO8601")) { timeFormatter = DateTimeFormatter.ISO_DATE_TIME; } else if (formatOrConstant.equalsIgnoreCase("SHORT")) { timeFormatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT); } else if (formatOrConstant.equalsIgnoreCase("MEDIUM")) { timeFormatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM); } else if (formatOrConstant.equalsIgnoreCase("LONG")) { timeFormatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG); } else if (formatOrConstant.equalsIgnoreCase("FULL")) { timeFormatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL); } else { try { timeFormatter = DateTimeFormatter.ofPattern(formatOrConstant); } catch (IllegalArgumentException exp) { throw new IllegalArgumentException( "Cannot parse log date specification '" + formatOrConstant + "'." + "Must be either DEFAULT, NONE, ISO8601, SHORT, MEDIUM, LONG, FULL or a " + "format string parseable by DateTimeFormat. See " + "https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html"); } } return this; } } }