analysis

package
v0.5.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 12, 2026 License: MIT Imports: 21 Imported by: 0

Documentation

Overview

Package analysis は1回の走行(収集グループ)について、種類をまたいだ集計を出す。

alp / slow log / pprof は「サーバーの中で何が遅いか」を教えてくれるが、 「ベンチの利用者が何をしていて、得点がいつ・どこで生まれたか」は教えてくれない。 ここでは httplog の生ログと dbquery の結果を時刻で揃え、次の3つを出す。

  • 時系列: 一定幅の区間ごとのリクエスト数・エラー・応答時間と、SQL で取った系列(得点・母集団)
  • ライフサイクル: エンティティ(利用者・ライドなど)が状態を順に進む様子。区間ごとの到達数と所要時間
  • 内訳: SQL の結果表(配信者別の得点など)

回ごとの知識(どの SQL が得点か、どの状態を順に進むか)は analysis.yml と dbquery.yml に置き、 このパッケージには持たない。

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func LatestGroup added in v0.2.1

func LatestGroup(client *summary.Client) (string, error)

LatestGroup は httplog がある最新の収集グループを返す。 収集中(pending)のものも含める。走行直後に latest を引いて1つ前の走行が出ると、取り違えに気づけない。

func NormalizeUnixTime

func NormalizeUnixTime(x float64) float64

NormalizeUnixTime は秒・ミリ秒・マイクロ秒の unix 時刻を秒に揃える。 SQL 側で単位を揃えなくてよいように、桁で判定する。

func Pending added in v0.2.1

func Pending(client *summary.Client, groupId string) (int, error)

Pending は収集グループの httplog / dbquery のうち、まだ収集中のエントリの数を返す。

func RenderDiffMarkdown added in v0.3.0

func RenderDiffMarkdown(w io.Writer, d *Diff)

RenderDiffMarkdown は Diff を Markdown にする。

func RenderEndpointsMarkdown added in v0.5.2

func RenderEndpointsMarkdown(w io.Writer, groupId string, stats []EndpointStat)

RenderEndpointsMarkdown は走行全体のエンドポイント別の集計を表にする(CLI)。

func RenderMarkdown

func RenderMarkdown(w io.Writer, rep *Report)

RenderMarkdown は Report をエージェントの文脈にそのまま貼れる Markdown にする。

func RenderRunsMarkdown added in v0.5.0

func RenderRunsMarkdown(w io.Writer, resp *RunsResponse)

RenderRunsMarkdown は走行を1行ずつ並べた表にする。 系列は役割(score / driver / penalty)が付いたものを優先し、無ければ先頭から最大6本。

func RenderSessionMarkdown added in v0.5.1

func RenderSessionMarkdown(w io.Writer, d *SessionDetail)

func RenderSessionsMarkdown added in v0.5.1

func RenderSessionsMarkdown(w io.Writer, s *SessionsResponse, top int)

func RenderTransitionsMarkdown added in v0.5.1

func RenderTransitionsMarkdown(w io.Writer, t *TransitionsResponse)

Types

type BreakdownDef

type BreakdownDef struct {
	Name  string `yaml:"name"`
	Query string `yaml:"query"`
}

BreakdownDef は dbquery の結果表をそのまま出す。value 列があれば構成比を付ける。

type BreakdownDiff added in v0.3.0

type BreakdownDiff struct {
	Name string
	// Keyed は key / value 列があって行ごとに突き合わせられたか。false なら行数だけ比べる。
	Keyed      bool
	RowsBefore *int `json:",omitempty"`
	RowsAfter  *int `json:",omitempty"`
	// Top1 / Top3 は上位1件・3件の構成比(偏りの変化を見る)。
	Top1Before float64
	Top1After  float64
	Top3Before float64
	Top3After  float64
	// NewInTop は after で上位に入り、before の上位に無かった key。
	NewInTop []string `json:",omitempty"`
	Rows     []KeyDiff
}

type BreakdownResult

type BreakdownResult struct {
	Name    string
	Columns []string
	Rows    [][]string
	// Share は value 列があるときの構成比(Rows と同じ並び)。
	Share     []float64 `json:",omitempty"`
	TotalRows int
	Error     string `json:",omitempty"`
}

type Bucket

type Bucket struct {
	// Offset は区間の開始(Origin からの秒)。
	Offset   int `json:"OffsetSec"`
	Requests int
	S2xx     int
	S3xx     int
	S4xx     int
	S5xx     int
	// Canceled は 499(クライアントが待ちきれずに切った)。S4xx には入れない。
	Canceled  int                `json:"S499"`
	P50       float64            `json:"P50Sec"`
	P99       float64            `json:"P99Sec"`
	Endpoints map[string]int     `json:",omitempty"`
	Series    map[string]float64 `json:",omitempty"`
}

type Commit added in v0.5.0

type Commit struct {
	Hash    string
	Message string
	Ref     string `json:",omitempty"`
}

type Config

type Config struct {
	// Bucket は時系列の区間幅(秒)。
	Bucket int `yaml:"bucket"`
	// Top は内訳・エンドポイント表に出す件数。
	Top int `yaml:"top"`

	HTTPLog HTTPLogConfig `yaml:"httplog"`

	Series     []SeriesDef    `yaml:"series"`
	Breakdowns []BreakdownDef `yaml:"breakdowns"`
	Lifecycles []LifecycleDef `yaml:"lifecycles"`
}

Config は analysis.yml。

func ParseConfig

func ParseConfig(raw []byte) (*Config, error)

type ConfigHash added in v0.3.0

type ConfigHash struct {
	// Analysis は集計したときの analysis.yml。
	Analysis string
	// DBQuery は dbquery を実行したときの dbquery.yml(dbquery の結果に記録されている)。
	DBQuery string
}

ConfigHash の各値は設定ファイルの中身の SHA-256 の先頭12桁。取れなかったものは空。

type Diff added in v0.3.0

type Diff struct {
	Before string
	After  string
	Score  *ScoreDiff `json:",omitempty"`
	// Warnings は比較の前提が崩れているもの(設定の食い違い、片方の警告など)。
	Warnings []string `json:",omitempty"`

	Series     []SeriesDiff
	Requests   []MetricDiff
	Endpoints  []EndpointDiff
	Lifecycles []LifecycleDiff
	Breakdowns []BreakdownDiff
}

func Compare added in v0.3.0

func Compare(before, after *Report, top int) *Diff

Compare は before → after の差を出す。top はエンドポイント・内訳の行数の上限。

type EndpointDiff added in v0.3.0

type EndpointDiff struct {
	Key         string
	CountBefore int
	CountAfter  int
	ShareBefore float64
	ShareAfter  float64
}

type EndpointSeries added in v0.5.2

type EndpointSeries struct {
	Key    string
	Count  []int
	P50Sec []float64
	P99Sec []float64
	Errors []int
	S499   []int
}

type EndpointShare added in v0.5.0

type EndpointShare struct {
	Key   string
	Count int
	// Share は全リクエストに占める割合(0〜1)。
	Share float64
}

type EndpointStat added in v0.5.2

type EndpointStat struct {
	Key   string
	Count int
	// Share は走行全体のリクエストに占める割合(0〜1)。
	Share float64
	P50   float64 `json:"P50Sec"`
	P99   float64 `json:"P99Sec"`
	// Sum は応答時間の合計(alp の SUM と同じもの)。
	Sum    float64 `json:"SumSec"`
	Errors int     // 4xx + 5xx(499 を除く)
	S499   int
}

type EndpointTimeline added in v0.5.2

type EndpointTimeline struct {
	GroupId   string
	BucketSec int
	OffsetSec []int
	// Endpoints は件数の多い順。値の並びは OffsetSec と同じ。
	Endpoints []EndpointSeries
}

type HTTPLogConfig

type HTTPLogConfig struct {
	// Label は使う httplog の Label。空なら同じ収集の httplog を全部まとめる。
	Label string `yaml:"label"`
	// TimeKey は時刻の LTSV キー。msec(nginx の $msec)か time($time_local)。
	// 既定は msec で、行に無ければ time を見る。
	TimeKey string `yaml:"time_key"`
	// EntityKey はライフサイクルの識別子に使う LTSV キー(セッション cookie など)。
	EntityKey string `yaml:"entity_key"`
}

type Handler

type Handler struct {
	// contains filtered or unexported fields
}

Handler は /api/analysis を提供する。 trend と同じく自分自身の API から材料を読むので、収集タイプの実装には手を入れない。

func NewHandler

func NewHandler(selfURL string, store storage.Storage) (*Handler, error)

func (*Handler) RegisterHandlers

func (h *Handler) RegisterHandlers(g *echo.Group)

type Input

type Input struct {
	GroupId string
	// Origin は時系列の 0 秒(unix 秒)。GroupId の時刻 = 収集開始 = initialize の直後。
	Origin   float64
	Requests []Request
	// SkippedLines は時刻が読めず捨てた LTSV の行数。
	SkippedLines int
	Queries      map[string]*dbquery.QueryResult
	// Warnings は材料を集める段階で見つかった問題(収集中・収集失敗のエントリなど)。
	Warnings []string

	// Score はこの収集に紐づいたベンチのスコア。無ければ nil。
	Score *ScoreInfo
	// ConfigHash は集計に使った設定のハッシュ。走行間の比較で定義の食い違いを見つけるのに使う。
	ConfigHash ConfigHash
	// Commit は httplog に記録されたアプリのコミット。無ければ nil。
	Commit *Commit
}

Input は1回の収集から集めた材料。

func Load

func Load(client *summary.Client, cfg *Config, groupId string) (*Input, error)

Load は収集グループの httplog(生ログ)と dbquery の結果を集める。

type KeyDiff added in v0.3.0

type KeyDiff struct {
	Key    string
	Before *float64 `json:",omitempty"`
	After  *float64 `json:",omitempty"`
}

type LifecycleDef

type LifecycleDef struct {
	Name string `yaml:"name"`
	// Source は httplog(識別子 = httplog.entity_key、状態 = "METHOD 正規化済みURI")か、
	// query:<dbquery の name>(列 entity, state, t)。
	Source string `yaml:"source"`
	Steps  []Step `yaml:"steps"`
}

LifecycleDef はエンティティが順に進む状態の列。

type LifecycleDiff added in v0.3.0

type LifecycleDiff struct {
	Name           string
	EntitiesBefore *int `json:",omitempty"`
	EntitiesAfter  *int `json:",omitempty"`
	Steps          []StepDiff
}

type LifecycleResult

type LifecycleResult struct {
	Name string
	// Entities は最初の状態に到達したエンティティの数。
	Entities int
	Steps    []StepResult
	Error    string `json:",omitempty"`
}

type LifecycleSteps added in v0.5.1

type LifecycleSteps struct {
	Name  string
	Steps []string
}

type LifecycleSummary added in v0.5.0

type LifecycleSummary struct {
	Name     string
	Entities int
	// Reached は状態ごとの到達数(Steps の順)。
	Steps []StepReached
}

type MetricDiff added in v0.3.0

type MetricDiff struct {
	Name   string
	Before float64
	After  float64
}

type Normalizer

type Normalizer struct {
	// contains filtered or unexported fields
}

Normalizer は alp.yml の matching_groups で URI をまとめる。 alp と同じく、クエリ文字列を落としてから先頭から順に当て、最初に当たった正規表現を返す。

func NewNormalizer

func NewNormalizer(alpConfig []byte) (*Normalizer, error)

func (*Normalizer) Normalize

func (n *Normalizer) Normalize(uri string) string

type Quantiles

type Quantiles struct {
	P50 float64
	P90 float64
	P99 float64
	Max float64
}

type Report

type Report struct {
	GroupId    string
	Origin     time.Time
	Bucket     int        `json:"BucketSec"`
	Warnings   []string   `json:",omitempty"`
	Score      *ScoreInfo `json:",omitempty"`
	Commit     *Commit    `json:",omitempty"`
	ConfigHash ConfigHash

	// Totals は走行全体のリクエストの集計(収集開始より後のもの)。
	Totals Totals
	// SeriesStats は時系列の系列ごとの集計(累積の系列は除く)。
	SeriesStats []SeriesStat
	// EndpointStats は全エンドポイントの走行全体の集計(件数の多い順)。
	EndpointStats []EndpointStat

	Timeline   Timeline
	Lifecycles []LifecycleResult
	Breakdowns []BreakdownResult
}

JSON のキーには単位を付ける(…Sec は秒、Rate… / Share は 0〜1 の割合)。 AI がドキュメントを読まずに解釈できるようにするため。

func Analyze

func Analyze(cfg *Config, in *Input) *Report

Analyze は材料から Report を作る。

type Request

type Request struct {
	// T は unix 秒(小数あり)。
	T        float64
	Method   string
	Endpoint string // matching_groups でまとめた URI
	// URI はまとめる前の URI(クエリ文字列を含む)、Host は vhost(配信者のサブドメインなど)。
	// セッションの導線を1件ずつ見るときに使う。
	URI     string
	Host    string
	Status  int
	ReqTime float64
	Entity  string
}

Request は LTSV 1行ぶん。

func ParseLTSV

func ParseLTSV(data []byte, n *Normalizer, timeKey, entityKey string) ([]Request, int)

ParseLTSV は nginx の LTSV ログを読む。時刻が読めない行は飛ばし、その件数を返す。

func (*Request) Key

func (r *Request) Key() string

Key はライフサイクルの状態に使う文字列。

type RequestSummary added in v0.5.0

type RequestSummary struct {
	Requests     int
	S4xx         int
	S5xx         int
	S499         int
	P50          float64 `json:"P50Sec"`
	P99          float64 `json:"P99Sec"`
	PeakRequests int
}

type RunSummary added in v0.5.0

type RunSummary struct {
	GroupId    string
	Score      *ScoreInfo `json:",omitempty"`
	Commit     *Commit    `json:",omitempty"`
	ConfigHash ConfigHash
	// Warnings は収集中・失敗のエントリなど、この走行の集計が欠けている理由。
	Warnings []string `json:",omitempty"`

	Requests   RequestSummary
	Series     []SeriesStat
	Lifecycles []LifecycleSummary
	// TopEndpoints は件数の多いエンドポイント(構成の変化を追う)。
	TopEndpoints []EndpointShare
	// Endpoints は全エンドポイントの集計。?endpoints=1 のときだけ入る(走行数 × エンドポイント数で大きくなるため)。
	Endpoints []EndpointStat `json:",omitempty"`
}

func Summarize added in v0.5.0

func Summarize(rep *Report) RunSummary

Summarize は Report から推移を見るのに要る値だけを抜き出す。

type RunsResponse added in v0.5.0

type RunsResponse struct {
	// Runs は古い順(グラフの左から右)。
	Runs []RunSummary
}

type ScoreDiff added in v0.3.0

type ScoreDiff struct {
	Before *ScoreInfo `json:",omitempty"`
	After  *ScoreInfo `json:",omitempty"`
}

type ScoreInfo added in v0.3.0

type ScoreInfo struct {
	Value  int64
	Passed bool
}

type SeriesDef

type SeriesDef struct {
	Name  string `yaml:"name"`
	Query string `yaml:"query"`
	// Role は系列の役割。score(得点の項)/ driver(得点を生む母数)/ penalty(得点を減らすもの)。
	// 出力に載るだけで集計は変わらない。AI や比較で「どれが得点か」を設定から引けるようにする。
	Role string `yaml:"role"`
	// Agg は区間内の集約方法。sum(既定)/ count / max / last。
	Agg string `yaml:"agg"`
	// Cumulative を true にすると区間ごとの値に加えて累積を出す(得点の積み上がりを見る)。
	Cumulative bool `yaml:"cumulative"`
}

SeriesDef は dbquery の結果から作る時系列。 クエリの列: t(unix 時刻。秒/ミリ秒/マイクロ秒は桁で判定)、value(省略時は件数)、 series(任意。あれば値ごとに別系列 "<name>:<series>" になる)。

type SeriesDiff added in v0.3.0

type SeriesDiff struct {
	Name      string
	Role      string   `json:",omitempty"`
	Before    *float64 `json:",omitempty"`
	After     *float64 `json:",omitempty"`
	T50Before *int     `json:"T50SecBefore,omitempty"`
	T50After  *int     `json:"T50SecAfter,omitempty"`
	T90Before *int     `json:"T90SecBefore,omitempty"`
	T90After  *int     `json:"T90SecAfter,omitempty"`
}

SeriesDiff は系列1本。片方にしか無い系列は Before / After の片方が nil。

type SeriesStat added in v0.3.0

type SeriesStat struct {
	Name string
	// Role は系列の役割(score: 得点の項 / driver: 得点を生む母数 / penalty: 得点を減らすもの)。未設定なら空。
	Role string `json:",omitempty"`
	// Query は元の dbquery の name。ライフサイクルの開始・完了数は lifecycle:<name>。
	Query string `json:",omitempty"`
	// Agg は区間内の集約方法(sum / count / max / last)。ライフサイクルの開始・完了数は count。
	Agg string
	// Total は走行全体の値。sum / count は合計、max は最大、last は最後の区間の値。
	Total float64
	// T50 / T90 は sum / count の系列が合計の 50% / 90% に達した区間の終わり(収集開始からの秒)。
	// 得点が前倒しで積み上がるようになったか(終盤の失速が直ったか)を見る。
	T50 *int `json:"T50Sec,omitempty"`
	T90 *int `json:"T90Sec,omitempty"`
}

type SessionDetail added in v0.5.1

type SessionDetail struct {
	GroupId  string
	Summary  SessionSummary
	Requests []SessionRequest
}

type SessionReach added in v0.5.1

type SessionReach struct {
	Name string
	// Reached は順に到達した状態の数(0 ならこのライフサイクルに入っていない)。
	Reached int
	// LastStep は最後に到達した状態の名前。
	LastStep string `json:",omitempty"`
}

type SessionRequest added in v0.5.1

type SessionRequest struct {
	OffsetSec  float64
	Method     string
	Endpoint   string
	URI        string
	Host       string `json:",omitempty"`
	Status     int
	ReqTimeSec float64
	// Steps はこの要求で進んだライフサイクルの状態("viewer:enter" の形)。
	Steps []string `json:",omitempty"`
}

type SessionSummary added in v0.5.1

type SessionSummary struct {
	// ID は開始時刻順の連番(s001, s002, ...)。同じ材料なら同じ番号になる。
	ID string
	// Hosts は訪れた vhost(多い順、最大3件)。ISUCON13 なら配信者のサブドメイン。
	Hosts      []string `json:",omitempty"`
	StartSec   float64
	EndSec     float64
	Requests   int
	Errors     int // 4xx + 5xx(499 を除く)
	S499       int
	MaxReqSec  float64
	Lifecycles []SessionReach
}

type SessionsResponse added in v0.5.1

type SessionsResponse struct {
	GroupId string
	// Lifecycles は source: httplog のライフサイクルと状態名(Sessions[].Lifecycles の並び)。
	Lifecycles []LifecycleSteps
	// Total はセッションの総数(lifecycle で絞る前)。
	Total    int
	Sessions []SessionSummary
}

type Step

type Step struct {
	Name string `yaml:"name"`
	// Match は状態に当てる正規表現。
	Match string `yaml:"match"`
	// contains filtered or unexported fields
}

type StepDiff added in v0.3.0

type StepDiff struct {
	Name   string
	Before *StepResult `json:",omitempty"`
	After  *StepResult `json:",omitempty"`
}

type StepReached added in v0.5.0

type StepReached struct {
	Name    string
	Reached int
}

type StepResult

type StepResult struct {
	Name string
	// Reached はこの状態まで順に到達したエンティティの数。
	Reached int
	// Rate は1つ前の状態に到達したうち、この状態まで進んだ割合。
	Rate float64 `json:"RateFromPrev"`
	// StoppedHere はこの状態を最後に先へ進まなかったエンティティの数(離脱・途中で走行終了の両方を含む)。
	StoppedHere int
	// PerEntity は到達したエンティティ1つあたり、この状態のイベントが何回あったか(順序を問わない)。
	PerEntity float64
	// FromPrev は1つ前の状態からの所要秒数。
	FromPrev *Quantiles `json:"FromPrevSec,omitempty"`
}

type Timeline

type Timeline struct {
	// Series は Buckets[].Series に入っている系列名(表示順)。
	Series []string
	// Endpoints は件数の多いエンドポイント(Buckets[].Endpoints のキー)。
	Endpoints []string
	Buckets   []Bucket
}

func (Timeline) MarshalJSON added in v0.5.0

func (tl Timeline) MarshalJSON() ([]byte, error)

func (*Timeline) UnmarshalJSON added in v0.5.0

func (tl *Timeline) UnmarshalJSON(data []byte) error

type Totals added in v0.3.0

type Totals struct {
	Requests int
	S2xx     int
	S3xx     int
	S4xx     int
	S5xx     int
	Canceled int     `json:"S499"`
	P50      float64 `json:"P50Sec"`
	P99      float64 `json:"P99Sec"`
	// PeakRequests は区間あたりの最大リクエスト数、PeakOffset はその区間の開始。
	PeakRequests int
	PeakOffset   int `json:"PeakOffsetSec"`
	// Endpoints は全エンドポイントの件数(Timeline.Endpoints と違って上位に絞らない)。
	Endpoints map[string]int `json:",omitempty"`
}

type Transition added in v0.5.1

type Transition struct {
	From  string
	To    string
	Count int
	// ShareOfFrom は From の次の要求のうち、To が占める割合(0〜1)。
	ShareOfFrom float64
	// GapP50Sec は From から To までの間隔の中央値。
	GapP50Sec float64
}

Transition は「From の次に To を叩いた」回数。From が (開始) なら最初の要求、To が (終了) なら最後の要求。

type TransitionsResponse added in v0.5.1

type TransitionsResponse struct {
	GroupId   string
	Lifecycle string `json:",omitempty"`
	// Sessions は集計したセッションの数。
	Sessions    int
	Transitions []Transition
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL