if the file hasn't been settled, will auto set to external storage.

@return the log file used to log to external storage
189498
public synchronized File getLogFile() {

        File dir = getStorageDir();
        if (dir == null) {
            Log.e(TAG, "Unable to open log file from external storage");
            return null;
        }

        switch (wraper.nameFormat) {
            case WrapFormatter.NAME_FORMAT_DATE: {
                String file = getFormattedNameWithDate(dir);
                mLogFile = new File(dir, file);
            }
            break;
            case WrapFormatter.NAME_FORMAT_PLUSINDEX: {
                String file = getFormattedNameWithPlusIndex(dir);
                mLogFile = new File(dir, file);
            }
            break;
            case WrapFormatter.NAME_FORMAT_NONE: {
                mLogFile = new File(dir, getFileName(fileName).concat(DEFUALT_FILE_EXT));
            }
            break;
            default: {
                mLogFile = new File(dir, getFileName(fileName).concat(DEFUALT_FILE_EXT));
            }
            break;
        }

        try {
            mLogFile.getParentFile().mkdirs();
            mLogFile.createNewFile();
        } catch (IOException e) {
            Log.e(TAG, "创建文件失败了..." + e.toString() + " mLogFile.getParentFile()");
        }

        return mLogFile;
    }
460331
public function getLogFile() {

        if ($this->_fp === null) {
            $this->LOG_DIR = ROOT .DS. 'app' . DS .  'logs';
            $filename      = $this->LOG_DIR . DS . date("Y-m-d");
            $this->_fp     = fopen($filename, 'a');
            if ($this->_fp === false) {
                throw new LoggerException('Cannot open log file: ' . $filename);
            }
            chmod($filename, 0774);
        }

        return $this->_fp;

    }
387221
public int getStorageStrategy()
  {
    if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
      SibTr.entry(this, tc, "getStorageStrategy");

    int storageStrategy;

    storageStrategy = STORE_ALWAYS;

    if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
      SibTr.exit(tc, "getStorageStrategy", new Integer(storageStrategy));

    return storageStrategy;
  }
1211542
def log_file(self):
        
        log_file = self.get('log')
        if not log_file:
            log_file = '%s.log' % (self.name)
            self.set('log', log_file)
        return os.path.join(self.initial_dir, self.get('log'))
1348909
public String logDirectory()
    {
        if (tc.isEntryEnabled())
            Tr.entry(tc, "logDirectory", this);
        if (tc.isEntryEnabled())
            Tr.exit(tc, "logDirectory", _logDirectory);
        return _logDirectory;
    }
1344001
private void writePendingToFile() throws java.io.IOException, InternalLogException, LogIncompatibleException
    {
        if (tc.isEntryEnabled())
            Tr.entry(tc, "writePendingToFile");

        synchronized (_pendingWriteList)
        {
            LogRecord[] records = (LogRecord[]) _pendingWriteList.toArray(new LogRecord[0]);

            // Don't use vectored IO unless we're told to.
            if (!Boolean.getBoolean("com.ibm.ws.recoverylog.spi.UseVectoredIO"))
            {
                // Put the file header at the front of the list
                ByteBuffer header = (ByteBuffer) _fileBuffer.duplicate().position(0).limit(_logFileHeader.length());
                _fileChannel.write(header, 0);

                // Write the remainder of the list
                for (int i = 0; i < records.length; i++)
                {
                    if (tc.isDebugEnabled())
                        Tr.debug(tc, "Performing write at position " + records[i].absolutePosition());
                    _fileChannel.write((ByteBuffer) records[i]._buffer.flip(), records[i].absolutePosition());
                }
            }
            else
            {
                // Sort the records into ascending order based on their absolute
                // position in the file.  We're going to try and keep the disk
                // moving forward.
                Arrays.sort(records, _recordComparator);

                // Now separate the records into two arrays:
                //   o ByteBuffers of data
                //   o Absolute File positions
                ByteBuffer[] buffers = new ByteBuffer[records.length + 1];
                int[] positions = new int[records.length + 1];

                for (int i = 0; i < records.length; i++)
                {
                    buffers[i + 1] = (ByteBuffer) records[i]._buffer.flip();
                    positions[i + 1] = records[i].absolutePosition();
                }

                // Put the file header at the front of the list
                buffers[0] = (ByteBuffer) _fileBuffer.duplicate().position(0).limit(_logFileHeader.length());
                positions[0] = 0;

                // Here's where we go through the list and attempt to write
                // batches of adjacent records using vectored I/O.
                int idx = 0;
                while (idx < buffers.length)
                {
                    int min = idx;
                    int max = idx;

                    // Somewhere in the middle
                    while (max <= (buffers.length - 2))
                    {
                        if (positions[max + 1] == (positions[max] + buffers[max].remaining()))
                            max++;
                    }

                    // Do the actual writes                    
                    _fileChannel.position(positions[min]);
                    _fileChannel.write(buffers, min, (max - min + 1));

                    // Go back and find the next batch
                    idx = max + 1;
                }
            }

            // Cleanup the pending write list for the next force
            _pendingWriteList.clear();
        }

        if (tc.isEntryEnabled())
            Tr.exit(tc, "writePendingToFile");
    }
1107059
public long getLogFileSpaceLeft()
    {
        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.entry(this, cclass
                        , "getLogFileSpaceLeft"
                            );

        long logFileSpaceLeft = objectManagerState.logOutput.getLogFileSpaceLeft();

        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.exit(this, cclass
                       , "getLogFileSpaceLeft"
                       , "returns"
                         + " logFileSpaceLeft=" + logFileSpaceLeft + "(long)"
                            );
        return logFileSpaceLeft;
    }
1102792
public synchronized ChangedFile reserve() {
        if (fileList.isEmpty() || shutdown) {
            return null;
        }

        String key = fileList.keySet().iterator().next();
        ChangedFile changedFile = fileList.remove(key);
        reservedFiles.put(key, changedFile);
        incrementVersion();
        fireChangedEventAsync();
        return changedFile;
    }
835333
protected long getLogSpaceReserved() {
        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.entry(this, cclass
                        , "getLogSpaceReserved"
                          + ")");

        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.exit(this, cclass
                       , "getLogSpaceReserved"
                       , "returns logSpaceReserved=" + logSpaceReserved + "(long)"
                            );
        return logSpaceReserved;
    }
1211361
LoggingOptions getLoggingOptions() {
    if (loggingOptions == null) {
      if (Strings.isNullOrEmpty(credentialsFile)) {
        loggingOptions = LoggingOptions.getDefaultInstance();
      } else {
        try {
          loggingOptions =
              LoggingOptions.newBuilder()
                  .setCredentials(
                      GoogleCredentials.fromStream(new FileInputStream(credentialsFile)))
                  .build();
        } catch (IOException e) {
          throw new RuntimeException(
              String.format(
                  "Could not read credentials file %s. Please verify that the file exists and is a valid Google credentials file.",
                  credentialsFile),
              e);
        }
      }
    }
    return loggingOptions;
  }
374099
private String parseTransactionLogDirectory() {
        if (tc.isDebugEnabled())
            Tr.debug(tc, "parseTransactionLogDirectory working with " + _props);

        String configuredLogDir = (String) _props.get("transactionLogDirectory");
        // don't allow null to be returned - it will result in use of a location
        // that is shared
        // across all local servers and thus risks log corruption
        if (configuredLogDir == null) {
            if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled())
                Tr.debug(tc, "using default log dir as config is null");
            // set default
            configuredLogDir = defaultLogDir;
        } else {
            // ensure dir string ends with a '/'
            if (!configuredLogDir.endsWith("/")) {
                configuredLogDir = configuredLogDir + "/";
            }
        }

        // resolve the configured value
        WsResource logDirResource = null;
        try {
            // Synchronize to ensure we see a valid locationService
            synchronized (this) {
                logDirResource = locationService.resolveResource(configuredLogDir);
            }
        } catch (IllegalArgumentException e) {
            if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled())
                Tr.debug(tc, "IllegalArgumentException from location service for dir string: " + configuredLogDir);
            if (!configuredLogDir.equals(defaultLogDir)) {
                // try using the default
                configuredLogDir = defaultLogDir;
                try {
                    // Synchronize to ensure we see a valid locationService
                    synchronized (this) {
                        logDirResource = locationService.resolveResource(configuredLogDir);
                    }
                } catch (IllegalArgumentException ex) {
                    if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled())
                        Tr.debug(tc, "Secondary IllegalArgumentException " + ex + " from location service for dir string: " + configuredLogDir);
                    // if we can't establish a tran log dir, we need a way to disable
                    // the transaction service
                    // rethrow the original exception
                    throw e;
                }
            } else {
                throw e;
            }
        }

        // get full path string from resource
        logDir = logDirResource.toExternalURI().getPath();

        return logDir;
    }
873087
private void rolloverLogTask()
  {
    try {
      if (_isInit) {
        flush();
      }
    } catch (Exception e) {
      log.log(Level.WARNING, e.toString(), e);
    }

    _isRollingOver = true;
    
    try {
      if (! _isInit)
        return;
      
      Path savedPath = null;

      long now = CurrentTime.currentTime();

      long lastPeriodEnd = _nextPeriodEnd;

      _nextPeriodEnd = nextRolloverTime(now);

      Path path = getPath();

      synchronized (_logLock) {
        flushTempStream();

        long length = Files.size(path);
        
        if (lastPeriodEnd <= now && lastPeriodEnd > 0) {
          closeLogStream();

          savedPath = getSavedPath(lastPeriodEnd - 1);
        }
        else if (path != null && getRolloverSize() <= length) {
          closeLogStream();

          savedPath = getSavedPath(now);
        }
      }
      
      // archiving of path is outside of the synchronized block to
      // avoid freezing during archive
      if (savedPath != null) {
        movePathToArchive(savedPath);
      }
    } catch (IOException e) {
      e.printStackTrace();
    } finally {
      synchronized (_logLock) {
        _isRollingOver = false;
        flushTempStream();
      }
      
      _rolloverListener.requeue(_rolloverAlarm);
    }
  }
1007265
private void transferLogFilesToS3() {
        if (_fileTransfersEnabled) {
            // Find all closed log files in the staging directory and move them to S3
            for (final File logFile : _stagingDir.listFiles((dir, name) -> name.startsWith(_logFilePrefix) && name.endsWith(COMPRESSED_FILE_SUFFIX))) {
                // Extract the date portion of the file name and is it to partition the file in S3
                String auditDate = logFile.getName().substring(_logFilePrefix.length() + 1, _logFilePrefix.length() + 9);
                String dest = String.format("%s/date=%s/%s", _s3AuditRoot, auditDate, logFile.getName());

                _fileTransferService.submit(() -> {
                    // Since file transfers are done in a single thread, there shouldn't be any concurrency issues,
                    // but verify the same file wasn't submitted previously and is already transferred.
                    if (logFile.exists()) {
                        try {
                            PutObjectResult result = _s3.putObject(_s3Bucket, dest, logFile);
                            _log.debug("Audit log copied: {}, ETag={}", logFile, result.getETag());

                            if (!logFile.delete()) {
                                _log.warn("Failed to delete file after copying to s3: {}", logFile);
                            }
                        } catch (Exception e) {

                            // Log the error, try again on the next iteration
                            _rateLimitedLog.error(e, "Failed to copy log file {}", logFile);
                        }
                    }
                });
            }
        }

    }
779999
public static LogFactory get() {
		if (null == currentLogFactory) {
			synchronized (lock) {
				if (null == currentLogFactory) {
					currentLogFactory = LogFactory.create();
				}
			}
		}
		return currentLogFactory;
	}
116273
protected static Long getTotalExternalStorage() {
        try {
            if (isExternalStorageMounted()) {
                File path = Environment.getExternalStorageDirectory();
                StatFs stat = new StatFs(path.getPath());
                long blockSize = stat.getBlockSize();
                long totalBlocks = stat.getBlockCount();
                return totalBlocks * blockSize;
            }
        } catch (Exception e) {
            Log.e(TAG, "Error getting total external storage amount.", e);
        }

        return null;
    }
932191
public static File getLogsRoot() {
        String tagsLogsPath = SystemProperties.getString(LOGS_ROOT_PATH_PROPERTY);
        if (tagsLogsPath == null) {
            return new File(Jenkins.get().getRootDir(), "logs");
        } else {
            Level logLevel = Level.INFO;
            if (ALREADY_LOGGED) {
                logLevel = Level.FINE;
            }
            LOGGER.log(logLevel,
                       "Using non default root path for tasks logging: {0}. (Beware: no automated migration if you change or remove it again)",
                       LOGS_ROOT_PATH_PROPERTY);
            ALREADY_LOGGED = true;
            return new File(tagsLogsPath);
        }
    }
829632
private File getStorageDir() {
        String externalStorageState = Environment.getExternalStorageState();
        if (!externalStorageState.equals(Environment.MEDIA_MOUNTED)) {
            return null;
        }

        // 默认在外置程序包下面.logs 文件夹
        File file = getExternalStorageDirectory();

        if (fileName.startsWith("/")) {
            File tmp = new File(fileName);
            if (tmp.isDirectory())
                return tmp;

            return new File(file, getFileNameWithoutExtension(fileName));
        }

        String tmp = Environment.getExternalStorageDirectory().getPath();
        if (fileName.startsWith(tmp)) {
            file = new File(file, fileName.replace(tmp, ""));
            return file;
        }

        file = new File(file, "logs");
        file.mkdirs();
        return file;
    }