A Microscopically small logging framework
| 19 | * A Microscopically small logging framework |
| 20 | */ |
| 21 | public class Log { |
| 22 | |
| 23 | static protected ConcurrentLinkedDeque<Pair<Pattern, BiConsumer<String, Object>>> active = new ConcurrentLinkedDeque<>(); |
| 24 | static protected Cache<String, String> earlyFail = CacheBuilder.newBuilder().concurrencyLevel(2).maximumSize(100).build(); |
| 25 | |
| 26 | // we default to logging everything |
| 27 | static protected |
| 28 | BiConsumer<String, Supplier<Object>> _fallthrough = (x, y) -> println(x, y==null ? null : y.get()); |
| 29 | |
| 30 | // Use -------------------------------- |
| 31 | |
| 32 | static public void log(String channel, Supplier<Object> message) { |
| 33 | boolean found = false; |
| 34 | if (earlyFail.getIfPresent(channel) == null) { |
| 35 | for (Pair<Pattern, BiConsumer<String, Object>> p : active) { |
| 36 | if (p.first.matcher(channel).matches()) { |
| 37 | Object m = message.get(); |
| 38 | if (m != null) p.second.accept(channel, m); |
| 39 | found = true; |
| 40 | break; |
| 41 | } |
| 42 | } |
| 43 | if (!found) earlyFail.put(channel, channel); |
| 44 | } |
| 45 | if (!found && _fallthrough != null) _fallthrough.accept(channel, message); |
| 46 | } |
| 47 | |
| 48 | // Configure -------------------------------- |
| 49 | |
| 50 | /** |
| 51 | * adds a pattern to be logged. This rule is of higher priority than anything previously called "on" (and lower than anything subsequently |
| 52 | * called "on"). |
| 53 | */ |
| 54 | static public void add(String pattern, BiConsumer<String, Object> to) { |
| 55 | earlyFail.invalidateAll(); |
| 56 | active.addFirst(new Pair<>(Pattern.compile(pattern), to)); |
| 57 | } |
| 58 | |
| 59 | /** |
| 60 | * adds a pattern to be logged. This rule is of higher priority than anything previously called "on" (and lower than anything subsequently |
| 61 | * called "on"). Previous rules identical to "pattern" are removed. |
| 62 | */ |
| 63 | static public void on(String pattern, BiConsumer<String, Object> to) { |
| 64 | off(pattern); |
| 65 | add(pattern, to); |
| 66 | } |
| 67 | |
| 68 | /** |
| 69 | * turns a pattern off, by removing anything else associated with this pattern. If other rules (including the default) capture this output it |
| 70 | * will still be logged |
| 71 | */ |
| 72 | static public void off(String pattern) { |
| 73 | earlyFail.invalidateAll(); |
| 74 | Iterator<Pair<Pattern, BiConsumer<String, Object>>> i = active.iterator(); |
| 75 | while (i.hasNext()) { |
| 76 | if (i.next().first.equals(pattern)) i.remove(); |
| 77 | } |
| 78 | } |
nothing calls this directly
no test coverage detected