ttomcat-1778514358873.zip-extract/apache-tomcat-11.0.18-src/java/org/apache/juli/AsyncFileHandler.java

Path
ttomcat-1778514358873.zip-extract/apache-tomcat-11.0.18-src/java/org/apache/juli/AsyncFileHandler.java
Status
scanned
Type
file
Name
AsyncFileHandler.java
Extension
.java
Programming language
Java
Mime type
text/plain
File type
ASCII text, with CRLF line terminators
Tag

      
    
Rootfs path

      
    
Size
8452 (8.3 KB)
MD5
4f109d14a591171e007dfef307bd6ea0
SHA1
af4d5693c74ae87c076ed50c8a82b962616af9ea
SHA256
a72cbe6ac97ac9fbc10bb1fd9650ee53b6dab0f6e4823fd8269d1d1b0090fef8
SHA512

      
    
SHA1_git
9b0e7fe7282c5eb0b823a5d9c2043a2bca0c0b37
Is binary

      
    
Is text
True
Is archive

      
    
Is media

      
    
Is legal

      
    
Is manifest

      
    
Is readme

      
    
Is top level

      
    
Is key file

      
    
AsyncFileHandler.java | 8.3 KB |

/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.juli; import java.util.concurrent.LinkedBlockingDeque; import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.RejectedExecutionHandler; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import java.util.logging.LogRecord; /** * A {@link FileHandler} implementation that uses a queue of log entries. * <p> * Configuration properties are inherited from the {@link FileHandler} class. This class does not add its own * configuration properties for the logging configuration, but relies on the following system properties instead: * </p> * <ul> * <li><code>org.apache.juli.AsyncOverflowDropType</code> Default value: <code>1</code></li> * <li><code>org.apache.juli.AsyncMaxRecordCount</code> Default value: <code>10000</code></li> * </ul> * <p> * See the System Properties page in the configuration reference of Tomcat. * </p> */ public class AsyncFileHandler extends FileHandler { static final String THREAD_PREFIX = "AsyncFileHandlerWriter-"; public static final int OVERFLOW_DROP_LAST = 1; public static final int OVERFLOW_DROP_FIRST = 2; public static final int OVERFLOW_DROP_FLUSH = 3; public static final int OVERFLOW_DROP_CURRENT = 4; public static final int DEFAULT_OVERFLOW_DROP_TYPE = 1; public static final int DEFAULT_MAX_RECORDS = 10000; public static final int OVERFLOW_DROP_TYPE = Integer.parseInt( System.getProperty("org.apache.juli.AsyncOverflowDropType", Integer.toString(DEFAULT_OVERFLOW_DROP_TYPE))); public static final int MAX_RECORDS = Integer .parseInt(System.getProperty("org.apache.juli.AsyncMaxRecordCount", Integer.toString(DEFAULT_MAX_RECORDS))); private static final LoggerExecutorService LOGGER_SERVICE = new LoggerExecutorService(OVERFLOW_DROP_TYPE, MAX_RECORDS); private final Object closeLock = new Object(); protected volatile boolean closed = false; private final LoggerExecutorService loggerService; public AsyncFileHandler() { this(null, null, null); } public AsyncFileHandler(String directory, String prefix, String suffix) { this(directory, prefix, suffix, null); } public AsyncFileHandler(String directory, String prefix, String suffix, Integer maxDays) { this(directory, prefix, suffix, maxDays, LOGGER_SERVICE); } AsyncFileHandler(String directory, String prefix, String suffix, Integer maxDays, LoggerExecutorService loggerService) { super(directory, prefix, suffix, maxDays); loggerService.registerHandler(); this.loggerService = loggerService; } @Override public void close() { if (closed) { return; } synchronized (closeLock) { if (closed) { return; } closed = true; } loggerService.deregisterHandler(); super.close(); } @Override public void open() { if (!closed) { return; } synchronized (closeLock) { if (!closed) { return; } closed = false; } loggerService.registerHandler(); super.open(); } @Override public void publish(LogRecord record) { if (!isLoggable(record)) { return; } // fill source entries, before we hand the record over to another // thread with another class loader record.getSourceMethodName(); loggerService.execute(() -> { /* * During Tomcat shutdown, the Handlers are closed before the executor queue is flushed therefore the closed * flag is ignored if the executor is shutting down. */ if (!closed || loggerService.isTerminating()) { publishInternal(record); } }); } protected void publishInternal(LogRecord record) { super.publish(record); } static class LoggerExecutorService extends ThreadPoolExecutor { private static final ThreadFactory THREAD_FACTORY = new ThreadFactory(THREAD_PREFIX); /* * Implementation note: Use of this count could be extended to start/stop the LoggerExecutorService but that * would require careful locking as the current size of the queue also needs to be taken into account and there * are lost of edge cases when rapidly starting and stopping handlers. */ private final AtomicInteger handlerCount = new AtomicInteger(); LoggerExecutorService(final int overflowDropType, final int maxRecords) { super(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingDeque<>(maxRecords), THREAD_FACTORY); switch (overflowDropType) { case OVERFLOW_DROP_FIRST -> setRejectedExecutionHandler(new DiscardOldestPolicy()); case OVERFLOW_DROP_FLUSH -> setRejectedExecutionHandler(new DropFlushPolicy()); case OVERFLOW_DROP_CURRENT -> setRejectedExecutionHandler(new DiscardPolicy()); default -> setRejectedExecutionHandler(new DropLastPolicy()); } } @Override public LinkedBlockingDeque<Runnable> getQueue() { return (LinkedBlockingDeque<Runnable>) super.getQueue(); } public void registerHandler() { handlerCount.incrementAndGet(); } public void deregisterHandler() { int newCount = handlerCount.decrementAndGet(); if (newCount == 0) { try { Thread dummyHook = new Thread(); Runtime.getRuntime().addShutdownHook(dummyHook); Runtime.getRuntime().removeShutdownHook(dummyHook); } catch (IllegalStateException ise) { // JVM is shutting down. // Allow up to 10s for the queue to be emptied shutdown(); try { awaitTermination(10, TimeUnit.SECONDS); } catch (InterruptedException e) { // Ignore } shutdownNow(); } } } } private static class DropFlushPolicy implements RejectedExecutionHandler { @Override public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { while (true) { if (executor.isShutdown()) { break; } try { if (executor.getQueue().offer(r, 1000, TimeUnit.MILLISECONDS)) { break; } } catch (InterruptedException e) { Thread.currentThread().interrupt(); throw new RejectedExecutionException("Interrupted", e); } } } } private static class DropLastPolicy implements RejectedExecutionHandler { @Override public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { if (!executor.isShutdown()) { ((LoggerExecutorService) executor).getQueue().pollLast(); executor.execute(r); } } } }
Detected license expression
apache-2.0
Detected license expression (SPDX)
Apache-2.0
Percentage of license text
15.7
Copyrights

      
    
Holders

      
    
Authors

      
    
License detections License expression License expression SPDX
apache_2_0-4bde3f57-78aa-4201-96bf-531cba09e7de apache-2.0 Apache-2.0
URL Start line End line
http://www.apache.org/licenses/LICENSE-2.0 9 9