有没有办法在Windows中创建最新文件的链接/符号链接/快捷方式?继续拖尾最新的日志文件

时间:2018-05-05 01:55:24

标签: windows powershell logging

我搜索了高低,找到了如何在* nix中进行,但没有关于Windows。

首先,我看到这是Tomcat的catalina.out,现在我想知道如何在Windows上做类似的事情:考虑创建日志文件的文件夹,如何制作文件读取/指向创建的最新日志?

我认为Powershell解决方案可能是可能的,但老实说,我无法思考或找到任何方法来实现它。

(编辑)你们贬低的人至少可以发表评论告诉我,我做错了什么,或者我该如何改进这个问题?

(编辑)这里的想法是有一些方法来创建指向文件夹中最新日志文件的符号链接,因此程序可以始终监视相同的文件,无论最新文件是否更改其名称 - 如tail -f catalina.out始终会读取最新的catalina日志文件。

我能看到并且我想避免的唯一出路是编写一个PowerShell脚本来监视文件夹(https://superuser.com/questions/226828/how-to-monitor-a-folder-and-trigger-a-command-line-action-when-a-file-is-created)并动态创建符号链接到找到的最新文件({ {3}}),然后将其设置为服务,因此它将始终在后台运行。

1 个答案:

答案 0 :(得分:2)

不是寻找动态自我更新的符号链接(实现起来非常麻烦 - 请参阅问题评论中BACON的有用提示),您可以将其作为一个PowerShell 后台作业 的自助功能/脚本:

  • 循环中运行,该循环定期从后台作业获取最新的日志文件行,后台作业通过tail -f执行相当于Unix Get-Content -Wait -Tail 10

  • 如果找到新的日志文件,请终止上一个后台作业并为新日志文件启动一个。

请注意,这依赖于尾随日志的后台作业的定期轮询。下面的代码允许您调整轮询间隔 请注意,Get-Content -Wait本身会每秒轮询目标文件以进行更改。

这是代码;运行$VerbosePreference = 'Continue'以查看循环内部的内容:

$dir = 'C:\path\to\logs' # the log-file directory
$logFilePattern = '*.log' # wildcard pattern matching log files
$sleepIntervalMs = 1000  # how many msec. to sleep between getting new lines from the background job

Write-Host -ForegroundColor Green "Tailing the latest log(s) in $dir...`nPress any key to quit."
$currJob = $currLog = $null
while ($true) {

  # If the user pressed a key, clean up and exit.
  if ([console]::KeyAvailable) {
    $null = [console]::ReadKey($True) # consume the key - it will still have printed, though
    if ($currJob) { Remove-Job -Job $currJob -Force }
    break
  }

  # Get the latest lines from the current log from the background job.
  if ($currJob) {
    Write-Verbose "Checking for new lines in $newLog..."
    Receive-Job -Job $currJob
    Start-Sleep -Milliseconds $sleepIntervalMs  # sleep a little
  }

  # Determine the first / newest log.
  $newLog = Get-ChildItem -LiteralPath $dir -Filter $logFilePattern | Sort-Object CreationTimeUtc -Descending | Select-Object -First 1
  if ($newLog.FullName -ne $currLog.FullName) { # new log file found.

    Write-Verbose "(New) log file found: $newLog"

    if ($currJob) {
        Write-Verbose "Terminating background job for previous log ($currLog)."
        Remove-Job -Job $currJob -Force
        # When a *new* log was just started, we show *all* lines (and keep listening for more).
        $tailArg = @{} 
    } else {
        # When we first start monitoring, we start with the *last 10* lines
        # of the current log (and keep listening for more).
        $tailArg = @{ Tail = 10 } # On first
    }

    $currLog = $newLog

    Write-Verbose "Starting background job for $currLog..."
    # Start the background job for the new log.
    $currJob = Start-Job { Get-Content -Wait @using:tailArg -LiteralPath $using:newLog.FullName }

  }

}
Write-Host -ForegroundColor Green "Terminated."
相关问题