見出し画像

TWSLA開発9日目:珍しいログを見つける機能をTF-IDFで作れたみたいで、かなり嬉しい

今朝は、以前から考えていたTF-IDFで珍しいログ(他のログとは違う)を見つける機能を作るのが楽しみで2時台に目が覚めました。早すぎるので二度寝しようと思いましたが、眠れないので、本を読んで3時ぐらいに二度寝しました。その頃、助手の猫さんが騒いでいましたが、かみさんがお世話したようです。次に起きたのは5時でした。

コンピューターのログは、だいたい同じようなものを繰り返し出しています。でも、何か特殊なことが発生すると、他とは違う珍しいログが出ることがあります。これを見つけると問題を調べる時の手がかりになります。人の目で見ていて偶然発見することがありますが、プログラムの力でなんとかしたいと、ずっと考えてきました。
なんとなくTF-IDF

が使えるのでは?と思っていました。
昨日、

の動画を観て、ぜったいいけると思いました。
動画の作者の方、ありがとうございます。

GO言語のTF-IDFパッケージは

がよさそうなので使ってみました。

  • 検索したログをすべてドキュメントとして登録

  • 検索したログのすべての組み合わせの類似度を計算

  • 他のログとの類似度の値が小さいものが、珍しいログのはず

  • 類似度がしきい値を超えたら計算を止めれば、高速化できるはず

という感じで作ってみました。

やっとできて試してみると

おお!何となく、できてそうです。
syslogサーバーを再起動したという67000件の中で1回しかないログを見つけています。実際に仕事で使ってみようと思います。

いちおう処理は、

	// TF-IDF
	tfidf := tf_idf.New(
		tf_idf.WithDefaultStopWords(),
	)
	for i, l := range results {
		aLines++
		tfidf.AddDocument(l)
	}
	for i, l1 := range results {
		sims := []float64{}
		done := true
		for j, l2 := range results {
			if i == j {
				continue
			}
			if s, err := tfidf.Compare(l1, l2); err == nil {
				sims = append(sims, s)
				if tfidfThreshold > 0 && tfidfThreshold < s {
					done = false
					break
				}
			}
		}
		if done {
			min, _ := stats.Min(sims)
			max, _ := stats.Max(sims)
			mean, _ := stats.Mean(sims)
			cHit++
			tfidfList = append(tfidfList, tfidfEnt{
				Log:  i,
				Min:  min,
				Mean: mean,
				Max:  max,
			})
		}
	}

のような感じです。

明日に続く

開発のための諸経費(機材、Appleの開発者、サーバー運用)に利用します。 ソフトウェアのマニュアルをnoteの記事で提供しています。 サポートによりnoteの運営にも貢献できるのでよろしくお願います。