1 /*
  2  * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.
  8  *
  9  * This code is distributed in the hope that it will be useful, but WITHOUT
 10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 12  * version 2 for more details (a copy is included in the LICENSE file that
 13  * accompanied this code).
 14  *
 15  * You should have received a copy of the GNU General Public License version
 16  * 2 along with this work; if not, write to the Free Software Foundation,
 17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 18  *
 19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 20  * or visit www.oracle.com if you need additional information or have any
 21  * questions.
 22  *
 23  */
 24 #ifndef SHARE_LOGGING_LOGFILESTREAMOUTPUT_HPP
 25 #define SHARE_LOGGING_LOGFILESTREAMOUTPUT_HPP
 26 
 27 #include "logging/logDecorators.hpp"
 28 #include "logging/logOutput.hpp"
 29 #include "runtime/os.hpp"
 30 #include "utilities/globalDefinitions.hpp"
 31 
 32 class LogDecorations;
 33 
 34 class LogFileStreamInitializer {
 35  public:
 36   LogFileStreamInitializer();
 37 };
 38 
 39 // Ensure the default log streams have been initialized (stdout, stderr) using the static initializer below
 40 static LogFileStreamInitializer log_stream_initializer;
 41 
 42 // Base class for all FileStream-based log outputs.
 43 class LogFileStreamOutput : public LogOutput {
 44  private:
 45   bool                _write_error_is_shown;
 46 
 47   int write_internal(const char* msg);
 48  protected:
 49   static const char* const FoldMultilinesOptionKey;
 50   FILE*               _stream;
 51   size_t              _decorator_padding[LogDecorators::Count];
 52   bool                _fold_multilines;
 53 
 54   LogFileStreamOutput(FILE *stream) : _write_error_is_shown(false), _stream(stream), _fold_multilines(false) {
 55     for (size_t i = 0; i < LogDecorators::Count; i++) {
 56       _decorator_padding[i] = 0;
 57     }
 58   }
 59 
 60   int write_decorations(const LogDecorations& decorations);
 61   bool flush();
 62 
 63  public:
 64   virtual int write(const LogDecorations& decorations, const char* msg);
 65   virtual int write(LogMessageBuffer::Iterator msg_iterator);
 66 };
 67 
 68 class LogStdoutOutput : public LogFileStreamOutput {
 69   friend class LogFileStreamInitializer;
 70  private:
 71   LogStdoutOutput() : LogFileStreamOutput(stdout) {
 72     set_config_string("all=warning");
 73   }
 74   virtual bool initialize(const char* options, outputStream* errstream) {
 75     return false;
 76   }
 77  public:
 78   virtual const char* name() const {
 79     return "stdout";
 80   }
 81 };
 82 
 83 class LogStderrOutput : public LogFileStreamOutput {
 84   friend class LogFileStreamInitializer;
 85  private:
 86   LogStderrOutput() : LogFileStreamOutput(stderr) {
 87     set_config_string("all=off");
 88   }
 89   virtual bool initialize(const char* options, outputStream* errstream) {
 90     return false;
 91   }
 92  public:
 93   virtual const char* name() const {
 94     return "stderr";
 95   }
 96 };
 97 
 98 extern LogStderrOutput &StderrLog;
 99 extern LogStdoutOutput &StdoutLog;
100 
101 class FileLocker : public StackObj {
102 private:
103     FILE *_file;
104 
105 public:
106     FileLocker(FILE *file) : _file(file) {
107       os::flockfile(_file);
108     }
109 
110     ~FileLocker() {
111       os::funlockfile(_file);
112     }
113 };
114 
115 #endif // SHARE_LOGGING_LOGFILESTREAMOUTPUT_HPP