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   static const char* const FoldMultilinesOptionKey;
 46   bool                _fold_multilines;
 47   bool                _write_error_is_shown;
 48 
 49  protected:
 50   FILE*               _stream;
 51   size_t              _decorator_padding[LogDecorators::Count];
 52 
 53   LogFileStreamOutput(FILE *stream) : _fold_multilines(false), _write_error_is_shown(false), _stream(stream) {
 54     for (size_t i = 0; i < LogDecorators::Count; i++) {
 55       _decorator_padding[i] = 0;
 56     }
 57   }
 58 
 59   int write_decorations(const LogDecorations& decorations);
 60   int write_internal(const LogDecorations& decorations, const char* msg);
 61   bool flush();
 62 
 63  public:
 64   virtual bool set_option(const char* key, const char* value, outputStream* errstream);
 65   virtual int write(const LogDecorations& decorations, const char* msg);
 66   virtual int write(LogMessageBuffer::Iterator msg_iterator);
 67   // Write API used by AsyncLogWriter
 68   virtual int write_blocking(const LogDecorations& decorations, const char* msg);
 69   virtual void describe(outputStream* out);
 70 };
 71 
 72 class LogStdoutOutput : public LogFileStreamOutput {
 73   friend class LogFileStreamInitializer;
 74  private:
 75   LogStdoutOutput() : LogFileStreamOutput(stdout) {
 76     set_config_string("all=warning");
 77   }
 78   virtual bool initialize(const char* options, outputStream* errstream) {
 79     return false;
 80   }
 81  public:
 82   virtual const char* name() const {
 83     return "stdout";
 84   }
 85 };
 86 
 87 class LogStderrOutput : public LogFileStreamOutput {
 88   friend class LogFileStreamInitializer;
 89  private:
 90   LogStderrOutput() : LogFileStreamOutput(stderr) {
 91     set_config_string("all=off");
 92   }
 93   virtual bool initialize(const char* options, outputStream* errstream) {
 94     return false;
 95   }
 96  public:
 97   virtual const char* name() const {
 98     return "stderr";
 99   }
100 };
101 
102 extern LogStderrOutput &StderrLog;
103 extern LogStdoutOutput &StdoutLog;
104 
105 class FileLocker : public StackObj {
106 private:
107     FILE *_file;
108 
109 public:
110     FileLocker(FILE *file) : _file(file) {
111       os::flockfile(_file);
112     }
113 
114     ~FileLocker() {
115       os::funlockfile(_file);
116     }
117 };
118 
119 #endif // SHARE_LOGGING_LOGFILESTREAMOUTPUT_HPP