CSVテスト結果ファイルからランプ期間中にテスト結果を削除する方法は?

CSVテスト結果ファイルからランプ期間中にテスト結果を削除する方法は?

CSVファイルにテスト結果があります。最初のフィールドにはミリ秒単位のタイムスタンプがあります。

以下はCSVファイルのサンプルレコードです。

1628689875326,327,3.1 HTTP Request /api/StaffPortal,200,OK,Concurrency Thread Group   SignIn-ThreadStarter 1-5,text,true,,73018,17,17

ランプアップ(開始時間から5分)およびランプダウン期間(過去5分)の間のテスト結果を削除し、フィルタリングされたテスト結果をCSVファイルに書きたいです。

ハードコードされた値を試してみました。

#!/usr/bin/awk -f

  BEGIN {
    endTime=1628689875326
    startTime=1628689875326-300*1000
    offset=1628689875326-3900*1000

    FS=","
    rowCount=0
  }
  {

    if ($1> startTime && $1<offset){
        rowCount++
        print $0
    }
  }

答え1

awkを呼び出すためにshebangを使用する代わりに、shebangを使用してシェルを呼び出し、次にawkを呼び出します。バラよりhttps://stackoverflow.com/a/61002754/1745001なぜ。

私はあなたがしたいことをします:

#!/usr/bin/env bash

awk -F',' '
    NR==FNR {
        if (NR==2) {
            fiveMins = 5*60*1000*1000
            begTime  = $1 + fiveMins
        }
        endTime = $1 - fiveMins
        next
    }
    (FNR==1) || ( (begTime <= $1) && ($1 <= endTime) ) {
        print
        rowCount++
    }
    END {
        print rowCount+0 | "cat>&2"
    }
' "$1" "$1"

tailまたは、次を使用して最後の行のタイムスタンプを取得できます。@GreenOnlineの返信)awkからファイルを2回読み取る代わりに:

#!/usr/bin/env bash

awk -v lastTime="$(tail -n 1 "$1" | cut -d',' -f1)" -F',' '
    NR==2 {
        fiveMins = 5*60*1000*1000
        begTime  = $1 + fiveMins
        endTime  = lastTime - fiveMins
    }
    (NR==1) || ( (begTime <= $1) && ($1 <= endTime) ) {
        print
        rowCount++
    }
    END {
        print rowCount+0 | "cat>&2"
    }
' "$1"

どちらにしても次のように呼び出すことができます。

scriptname input.csv > output.csv

> output.csvまたは、出力ファイル名をハードコーディングしても問題ない場合は、シェルスクリプトのawkスクリプトの後に追加してください。

上記は、CSVに出力に印刷したいヘッダー行があると仮定しています。

Shebangを使用せずにawkを呼び出すと、シェルを使用して最良の操作、つまり別のコマンドを呼び出し、スクリプト引数を複数回使用し、次にawkを呼び出すことで最良の操作、つまりテキストを処理できます。起動率 他の方法は、よりクリーンで強力で効率的なスクリプトです。

答え2

ハードコーディングされたソリューション

ハードコーディングされた時間スクリプトでは、問題は次のとおりです。

  • offsetより小さいstartTimeのでif条件は

    $1> startTime && $1<offset
    

    できるいいえそれは真実だ。

その理由はまだ5分(=300秒)がstartTime残っているのですが、まだ65分(=3900秒)が残っているからです。5*60offset65*60

解決策は、初期化プログラムを次に変更することです。

    startTime=1628689875326-3900*1000*1000
    offset=1628689875326-300*1000*1000

これにより、関連時間が次に設定されます。

endTime = 1628689875326
startTime = endTime - (3900*1000*1000) =  1624789875326
5 minutes before end = endTime - (300*1000*1000)  = 1628389875326

これで、次のログファイルが提供されます。

1624789875326,327,3.1 HTTP Request /api/StaffPortal,200,OK,Concurrency Thread Group   SignIn-ThreadStarter 1-5,text,true,,73018,17,17
1624789875327,327,3.1 HTTP Request /api/StaffPortal,200,OK,Concurrency Thread Group   SignIn-ThreadStarter 1-5,text,true,,73018,17,17
1628389875325,327,3.1 HTTP Request /api/StaffPortal,200,OK,Concurrency Thread Group   SignIn-ThreadStarter 1-5,text,true,,73018,17,17
1628389875326,327,3.1 HTTP Request /api/StaffPortal,200,OK,Concurrency Thread Group   SignIn-ThreadStarter 1-5,text,true,,73018,17,17
1628389875327,327,3.1 HTTP Request /api/StaffPortal,200,OK,Concurrency Thread Group   SignIn-ThreadStarter 1-5,text,true,,73018,17,17
1628689875326,327,3.1 HTTP Request /api/StaffPortal,200,OK,Concurrency Thread Group   SignIn-ThreadStarter 1-5,text,true,,73018,17,17

走る

more test.log | ./filter.awk

希望の結果を提供します

1624789875327,327,3.1 HTTP Request /api/StaffPortal,200,OK,Concurrency Thread Group   SignIn-ThreadStarter 1-5,text,true,,73018,17,17
1628389875325,327,3.1 HTTP Request /api/StaffPortal,200,OK,Concurrency Thread Group   SignIn-ThreadStarter 1-5,text,true,,73018,17,17

より良いソリューション - 開始時間を確認する

しかし、あなたの質問を詳しく調べてみると、いくつかのことが明確に定義されていないことがわかりました。

  • スクリプトでは、startTime実際のログの開始ではなく、フィルタの開始である可能性があります。ログの開始時間は5分前です。

    1624789875326 - 300*1000*1000 = 1624489875326
    
  • 時間はミリ秒単位だと言っ*1000*1000たけどマイクロ秒

それにもかかわらず、開始時間(ログファイルの最初の行から始まる)を自動的に見つけ、ランプ時間を計算してフィルタの開始時間を計算するソリューションがあります。

また、フィルタ時間の終わりも計算します(ハードコードされたスクリプトと同じ方法)。終了時間を入力する必要がありますが、、これはログの最後のタイムスタンプです。

#!/usr/bin/awk -f
  
  BEGIN {
    rampTimeMins=5
    rampTimeMillis=rampTimeMins*60*1000
    rampTimeMicros=rampTimeMins*60*1000*1000

    # Enter the start time
    # (not required, if NR conditional is used)
    startTime=0
    # Calculate Start filter time in microseconds 
    # (not required, if NR conditional is used)
    filterStartTime=startTime+rampTimeMicros

    # Enter the end time (required)
    endTime=1628689875326
    # Calculate End filter time in microseconds
    filterEndTime=endTime-rampTimeMicros

    FS=","
    rowCount=0
  }

  {
    if (NR==1){
      startTime=$1
      filterStartTime=startTime+rampTimeMicros
    }
    if ($1> filterStartTime && $1<filterEndTime){
      rowCount++
      print $0
    }
  }

  END {
    print rowCount
  }

注1:CSVの最初の行がヘッダーの場合は、NR==1次のように変更してください。NR==2

ノート2:マイクロ秒の代わりにミリ秒を使用するには、rampTimeMicrosに変更しますrampTimeMillis

以下は、次を含むサンプルログファイルです。追加ログの実際の開始時間である初期時間(フィルタの開始時間ではない)

1624489875326,327,3.1 HTTP Request /api/StaffPortal,200,OK,Concurrency Thread Group   SignIn-ThreadStarter 1-5,text,true,,73018,17,17
1624489875327,327,3.1 HTTP Request /api/StaffPortal,200,OK,Concurrency Thread Group   SignIn-ThreadStarter 1-5,text,true,,73018,17,17
1624789875326,327,3.1 HTTP Request /api/StaffPortal,200,OK,Concurrency Thread Group   SignIn-ThreadStarter 1-5,text,true,,73018,17,17
1624789875327,327,3.1 HTTP Request /api/StaffPortal,200,OK,Concurrency Thread Group   SignIn-ThreadStarter 1-5,text,true,,73018,17,17
1628389875325,327,3.1 HTTP Request /api/StaffPortal,200,OK,Concurrency Thread Group   SignIn-ThreadStarter 1-5,text,true,,73018,17,17
1628389875326,327,3.1 HTTP Request /api/StaffPortal,200,OK,Concurrency Thread Group   SignIn-ThreadStarter 1-5,text,true,,73018,17,17
1628389875327,327,3.1 HTTP Request /api/StaffPortal,200,OK,Concurrency Thread Group   SignIn-ThreadStarter 1-5,text,true,,73018,17,17
1628689875326,327,3.1 HTTP Request /api/StaffPortal,200,OK,Concurrency Thread Group   SignIn-ThreadStarter 1-5,text,true,,73018,17,17

どちらで実行するか

more test.log | ./filter.awk

以前と同じ結果を提供します

1624789875327,327,3.1 HTTP Request /api/StaffPortal,200,OK,Concurrency Thread Group   SignIn-ThreadStarter 1-5,text,true,,73018,17,17
1628389875325,327,3.1 HTTP Request /api/StaffPortal,200,OK,Concurrency Thread Group   SignIn-ThreadStarter 1-5,text,true,,73018,17,17
2

しかし、追加の行があります。


最終ソリューション - 終了時間を取得する

行を変更すると

    endTime=1628689875326

到着

    "tail -1 test.log | cut -d, -f1" | getline endTime

これで最後のタイムスタンプが得られたので、スクリプトを編集する必要はありません。今後スクリプトが実行されます。一般用途で製作

    "tail -1 "ARGV[1]" | cut -d, -f1" | getline endTime

あるいは、より良い方法は、(安全な側面を維持するために)次のように生成されたサブシェルに引用されたファイル名を渡すことです。エドのコメント:

生成されたサブシェルに引用符なしでファイル名を渡さないように変更します(これはすべてグロービング、トークン化、セキュリティなどを意味します"tail -1 "ARGV[1]")。"tail -1 \047"ARGV[1]"\047

\047一重引用符(FWIW:\042二重引用符)はどこにありますか?

"tail -1 \047"ARGV[1]"\047 | cut -d, -f1" | getline endTime

したがって、最終スクリプトは次のようになります。

#!/usr/bin/awk -f
  
  BEGIN {
    rampTimeMins=5
    rampTimeMillis=rampTimeMins*60*1000
    rampTimeMicros=rampTimeMins*60*1000*1000

    # Enter the start time
    # (not required, if NR conditional is used)
    startTime=0
    # Calculate Start filter time in microseconds 
    # (not required, if NR conditional is used)
    filterStartTime=startTime+rampTimeMicros

    # Derive the end time
    "tail -1 \047"ARGV[1]"\047 | cut -d, -f1" | getline endTime
    # Calculate End filter time in microseconds
    filterEndTime=endTime-rampTimeMicros

    FS=","
    rowCount=0
  }

  {
    if (NR==1){
      startTime=$1
      filterStartTime=startTime+rampTimeMicros
    }
    if ($1> filterStartTime && $1<filterEndTime){
      rowCount++
      print $0
    }
  }

  END {
    print rowCount
  }

注1:CSVの最初の行がヘッダーの場合は、NR==1次のように変更してください。NR==2

次のコマンド(filter.awk)を使用してスクリプトを実行します。

./filter.awk test.log

いいえ

more test.log | ./filter.awk

引用する:

答え3

与えられたサンプルスクリプトは、次の修正で更新されました。

  1. 入力ファイルの2行目の開始時刻に基づいてfilterStartTime合計を計算します。filterEndTime
  2. さらなる分析のためにファイルに出力を書き込む
#!/usr/bin/awk -f
  BEGIN {
    testDurationMins=60
    rampTimeMins=5
    outputFileName="test-result-filtered-without-rampup.jtl"

    rampTimeMillis=rampTimeMins*60*1000

    # Enter the start time
    # (not required, if NR conditional is used)
    startTime=0
    # Calculate Start filter time in milliseconds
    # (not required, if NR conditional is used)
    filterStartTime=startTime+rampTimeMillis

    # Filter end time
    filterEndTime=0

    # Calculate the test duration  in milliseconds
    testDurationMillis=testDurationMins*60*1000

    FS=","
    rowCount=0
  }
  {

    if (NR==1){
      #Write header to the output file
      print > outputFileName
    }
    if (NR==2){
      #Set the filter start and end times
      startTime=$1
      filterStartTime=startTime+rampTimeMillis
      filterEndTime=filterStartTime+testDurationMillis
    }
    if (NR>2 && $1> filterStartTime && $1<filterEndTime){
      rowCount++
      print >> outputFileName
    }
  }
  END {
    print "" rowCount
  }

関連情報