View Javadoc

    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one or more
    3    * contributor license agreements.  See the NOTICE file distributed with
    4    * this work for additional information regarding copyright ownership.
    5    * The ASF licenses this file to You under the Apache License, Version 2.0
    6    * (the "License"); you may not use this file except in compliance with
    7    * the License.  You may obtain a copy of the License at
    8    *
    9    *     http://www.apache.org/licenses/LICENSE-2.0
    10   *
    11   * Unless required by applicable law or agreed to in writing, software
    12   * distributed under the License is distributed on an "AS IS" BASIS,
    13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14   * See the License for the specific language governing permissions and
    15   * limitations under the License.
    16   */
    17
    18  package org.apache.logging.log4j.io;
    19
    20  import java.nio.CharBuffer;
    21
    22  import org.apache.logging.log4j.Level;
    23  import org.apache.logging.log4j.Marker;
    24  import org.apache.logging.log4j.spi.ExtendedLogger;
    25
    26  /**
    27   *
    28   * @since 2.1
    29   */
    30  public class CharStreamLogger {
    31      private final ExtendedLogger logger;
    32      private final Level level;
    33      private final Marker marker;
    34      private final StringBuilder msg = new StringBuilder();
    35      private boolean closed = false;
    36
    37      public CharStreamLogger(final ExtendedLogger logger, final Level level, final Marker marker) {
    38          this.logger = logger;
    39          this.level = level == null ? logger.getLevel() : level;
    40          this.marker = marker;
    41      }
    42
    43      public void close(final String fqcn) {
    44          synchronized (this.msg) {
    45              this.closed = true;
    46              logEnd(fqcn);
    47          }
    48      }
    49
    50      private void log(final String fqcn) {
    51          // convert to string now so async loggers work
    52          this.logger.logIfEnabled(fqcn, this.level, this.marker, this.msg.toString());
    53          this.msg.setLength(0);
    54      }
    55
    56      private void logEnd(final String fqcn) {
    57          if (this.msg.length() > 0) {
    58              log(fqcn);
    59          }
    60      }
    61
    62      public void put(final String fqcn, final char[] cbuf, final int off, final int len) {
    63          put(fqcn, CharBuffer.wrap(cbuf), off, len);
    64      }
    65
    66      public void put(final String fqcn, final CharSequence str, final int off, final int len) {
    67          if (len >= 0) {
    68              synchronized (this.msg) {
    69                  if (this.closed) {
    70                      return;
    71                  }
    72                  int start = off;
    73                  final int end = off + len;
    74                  for (int pos = off; pos < end; pos++) {
    75                      final char c = str.charAt(pos);
    76                      switch (c) {
    77                      case '\r':
    78                      case '\n':
    79                          this.msg.append(str, start, pos);
    80                          start = pos + 1;
    81                          if (c == '\n') {
    82                              log(fqcn);
    83                          }
    84                          break;
    85                      }
    86                  }
    87                  this.msg.append(str, start, end);
    88              }
    89          } else {
    90              logEnd(fqcn);
    91          }
    92      }
    93
    94      public void put(final String fqcn, final int c) {
    95          if (c >= 0) {
    96              synchronized (this.msg) {
    97                  if (this.closed) {
    98                      return;
    99                  }
    100                 switch (c) {
    101                 case '\n':
    102                     log(fqcn);
    103                     break;
    104                 case '\r':
    105                     break;
    106                 default:
    107                     this.msg.append((char) c);
    108                 }
    109             }
    110         } else {
    111             logEnd(fqcn);
    112         }
    113     }
    114 }