Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 12 additions & 7 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,15 @@ mock:
-source=internal/pkg/repository/repository.go \
-destination=internal/pkg/repository/mock/repository.go
PATH="$(LOCAL_BIN):$(PATH)" mockgen \
-source=internal/pkg/repository_ch/repository.go \
-destination=internal/pkg/repository_ch/mock/repository.go
-destination=internal/pkg/repository_ch/mock/repository_ch.go \
-package=mock_repositorych \
github.com/ozontech/seq-ui/internal/pkg/repository_ch \
Repository
PATH="$(LOCAL_BIN):$(PATH)" mockgen \
-destination=internal/pkg/repository_ch/mock/ch_driver.go \
-package=mock_repositorych \
github.com/ClickHouse/clickhouse-go/v2/lib/driver \
Conn,Rows,Row
PATH="$(LOCAL_BIN):$(PATH)" mockgen \
-source=internal/pkg/client/seqdb/client.go \
-destination=internal/pkg/client/seqdb/mock/client.go
Expand All @@ -102,11 +109,9 @@ mock:
-source=internal/pkg/cache/cache.go \
-destination=internal/pkg/cache/mock/cache.go
PATH="$(LOCAL_BIN):$(PATH)" mockgen \
-source=internal/app/auth/oidc.go \
-destination=internal/app/auth/mock/oidc.go
PATH="$(LOCAL_BIN):$(PATH)" mockgen \
-source=internal/app/auth/jwt.go \
-destination=internal/app/auth/mock/jwt.go
-destination=internal/app/auth/mock/auth.go \
github.com/ozontech/seq-ui/internal/app/auth \
OIDCProvider,JWTProvider

.PHONY: protoc
protoc:
Expand Down
157 changes: 96 additions & 61 deletions api/errorgroups/v1/errorgroups.proto
Original file line number Diff line number Diff line change
Expand Up @@ -13,104 +13,139 @@ service ErrorGroupsService {
rpc GetDetails(GetDetailsRequest) returns (GetDetailsResponse) {}
rpc GetReleases(GetReleasesRequest) returns (GetReleasesResponse) {}
rpc GetServices(GetServicesRequest) returns (GetServicesResponse) {}
rpc DiffByReleases(DiffByReleasesRequest) returns (DiffByReleasesResponse) {}
}

enum Order {
ORDER_FREQUENT = 0;
ORDER_LATEST = 1;
ORDER_OLDEST = 2;
ORDER_FREQUENT = 0;
ORDER_LATEST = 1;
ORDER_OLDEST = 2;
}

message GetGroupsRequest {
string service = 1;
optional string env = 2;
optional string release = 3;
google.protobuf.Duration duration = 4;
uint32 limit = 5;
uint32 offset = 6;
Order order = 7;
bool with_total = 8;
optional string source = 9;
message Filter {
bool is_new = 1;
}

string service = 1;
optional string env = 2;
optional string release = 3;
google.protobuf.Duration duration = 4;
uint32 limit = 5;
uint32 offset = 6;
Order order = 7;
bool with_total = 8;
optional string source = 9;
optional Filter filter = 10;
}

message GetGroupsResponse {
uint64 total = 1;
repeated Group groups = 2;
uint64 total = 1;
repeated Group groups = 2;
}

message Group {
uint64 hash = 1;
string message = 2;
uint64 seen_total = 3;
google.protobuf.Timestamp first_seen_at = 4;
google.protobuf.Timestamp last_seen_at = 5;
string source = 6;
uint64 hash = 1;
string message = 2;
uint64 seen_total = 3;
google.protobuf.Timestamp first_seen_at = 4;
google.protobuf.Timestamp last_seen_at = 5;
string source = 6;
}

message GetHistRequest {
string service = 1;
optional uint64 group_hash = 2;
optional string env = 3;
optional string release = 4;
optional google.protobuf.Duration duration = 5;
optional string source = 6;
string service = 1;
optional uint64 group_hash = 2;
optional string env = 3;
optional string release = 4;
optional google.protobuf.Duration duration = 5;
optional string source = 6;
}

message GetHistResponse {
repeated Bucket buckets = 1;
repeated Bucket buckets = 1;
}

message Bucket {
google.protobuf.Timestamp time = 1;
uint64 count = 2;
google.protobuf.Timestamp time = 1;
uint64 count = 2;
}

message GetDetailsRequest {
string service = 1;
uint64 group_hash = 2;
optional string env = 3;
optional string release = 4;
optional string source = 5;
string service = 1;
uint64 group_hash = 2;
optional string env = 3;
optional string release = 4;
optional string source = 5;
}

message GetDetailsResponse {
message Distribution {
string value = 1;
uint64 percent = 2;
}

message Distributions {
repeated Distribution by_env = 1;
repeated Distribution by_release = 2;
}

uint64 group_hash = 1;
string message = 2;
uint64 seen_total = 3;
google.protobuf.Timestamp first_seen_at = 4;
google.protobuf.Timestamp last_seen_at = 5;
Distributions distributions = 6;
map<string, string> log_tags = 7;
string source = 8;
message Distribution {
string value = 1;
uint64 percent = 2;
}

message Distributions {
repeated Distribution by_env = 1;
repeated Distribution by_release = 2;
}

uint64 group_hash = 1;
string message = 2;
uint64 seen_total = 3;
google.protobuf.Timestamp first_seen_at = 4;
google.protobuf.Timestamp last_seen_at = 5;
Distributions distributions = 6;
map<string, string> log_tags = 7;
string source = 8;
}

message GetReleasesRequest {
string service = 1;
reserved 2;
optional string env = 3;
string service = 1;
reserved 2;
optional string env = 3;
}

message GetReleasesResponse {
repeated string releases = 1;
repeated string releases = 1;
}

message GetServicesRequest {
string query = 1;
optional string env = 2;
uint32 limit = 3;
uint32 offset = 4;
string query = 1;
optional string env = 2;
uint32 limit = 3;
uint32 offset = 4;
}

message GetServicesResponse {
repeated string services = 1;
repeated string services = 1;
}

message DiffByReleasesRequest {
string service = 1;
repeated string releases = 2;
optional string env = 3;
optional string source = 4;
uint32 limit = 5;
uint32 offset = 6;
Order order = 7;
bool with_total = 8;
}

message DiffByReleasesResponse {
message ReleaseInfo {
uint64 seen_total = 1;
}

message Group {
uint64 hash = 1;
string message = 2;
google.protobuf.Timestamp first_seen_at = 3;
google.protobuf.Timestamp last_seen_at = 4;
string source = 5;
map<string, ReleaseInfo> release_infos = 6;
}

uint64 total = 1;
repeated Group groups = 2;
}
75 changes: 75 additions & 0 deletions internal/api/errorgroups/v1/grpc/diff_by_releases.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package grpc

import (
"context"

"github.com/ozontech/seq-ui/internal/api/grpcutil"
"github.com/ozontech/seq-ui/internal/app/types"
"github.com/ozontech/seq-ui/pkg/errorgroups/v1"
"github.com/ozontech/seq-ui/tracing"
"go.opentelemetry.io/otel/attribute"
"google.golang.org/protobuf/types/known/timestamppb"
)

func (a *API) DiffByReleases(ctx context.Context, req *errorgroups.DiffByReleasesRequest) (*errorgroups.DiffByReleasesResponse, error) {
ctx, span := tracing.StartSpan(ctx, "errorgroups_v1_diff_by_releases")
defer span.End()

attributes := []attribute.KeyValue{
{Key: "service", Value: attribute.StringValue(req.Service)},
{Key: "releases", Value: attribute.StringSliceValue(req.Releases)},
{Key: "limit", Value: attribute.IntValue(int(req.Limit))},
{Key: "offset", Value: attribute.IntValue(int(req.Offset))},
{Key: "order", Value: attribute.StringValue(req.Order.String())},
{Key: "with_total", Value: attribute.BoolValue(req.WithTotal)},
}
if req.Env != nil {
attributes = append(attributes, attribute.KeyValue{Key: "env", Value: attribute.StringValue(*req.Env)})
}
if req.Source != nil {
attributes = append(attributes, attribute.KeyValue{Key: "source", Value: attribute.StringValue(*req.Source)})
}
span.SetAttributes(attributes...)

groups, total, err := a.service.DiffByReleases(ctx, types.DiffByReleasesRequest{
Service: req.Service,
Releases: req.Releases,
Env: req.Env,
Source: req.Source,
Limit: req.Limit,
Offset: req.Offset,
Order: types.ErrorGroupsOrder(req.Order),
WithTotal: req.WithTotal,
})
if err != nil {
return nil, grpcutil.ProcessError(err)
}

return &errorgroups.DiffByReleasesResponse{
Total: total,
Groups: diffGroupsToProto(groups),
}, nil
}

func diffGroupsToProto(source []types.DiffGroup) []*errorgroups.DiffByReleasesResponse_Group {
groups := make([]*errorgroups.DiffByReleasesResponse_Group, 0, len(source))

for _, g := range source {
releaseInfos := make(map[string]*errorgroups.DiffByReleasesResponse_ReleaseInfo)
for release, info := range g.ReleaseInfos {
releaseInfos[release] = &errorgroups.DiffByReleasesResponse_ReleaseInfo{
SeenTotal: info.SeenTotal,
}
}
groups = append(groups, &errorgroups.DiffByReleasesResponse_Group{
Hash: g.Hash,
Message: g.Message,
FirstSeenAt: timestamppb.New(g.FirstSeenAt),
LastSeenAt: timestamppb.New(g.LastSeenAt),
Source: g.Source,
ReleaseInfos: releaseInfos,
})
}

return groups
}
2 changes: 1 addition & 1 deletion internal/api/errorgroups/v1/grpc/get_details.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (
)

func (a *API) GetDetails(ctx context.Context, req *errorgroups.GetDetailsRequest) (*errorgroups.GetDetailsResponse, error) {
_, span := tracing.StartSpan(ctx, "errorgroups_v1_get_groups")
ctx, span := tracing.StartSpan(ctx, "errorgroups_v1_get_details")
defer span.End()

attributes := []attribute.KeyValue{
Expand Down
20 changes: 19 additions & 1 deletion internal/api/errorgroups/v1/grpc/get_groups.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package grpc

import (
"context"
"encoding/json"
"time"

"go.opentelemetry.io/otel/attribute"
Expand All @@ -22,6 +23,7 @@ func (a *API) GetGroups(ctx context.Context, req *errorgroups.GetGroupsRequest)
{Key: "limit", Value: attribute.IntValue(int(req.Limit))},
{Key: "offset", Value: attribute.IntValue(int(req.Offset))},
{Key: "order", Value: attribute.StringValue(string(req.Order))},
{Key: "with_total", Value: attribute.BoolValue(req.WithTotal)},
}
if req.Env != nil {
attributes = append(attributes, attribute.KeyValue{Key: "env", Value: attribute.StringValue(*req.Env)})
Expand All @@ -35,6 +37,10 @@ func (a *API) GetGroups(ctx context.Context, req *errorgroups.GetGroupsRequest)
if req.Source != nil {
attributes = append(attributes, attribute.KeyValue{Key: "source", Value: attribute.StringValue(*req.Source)})
}
if req.Filter != nil {
filterRaw, _ := json.Marshal(req.Filter)
attributes = append(attributes, attribute.KeyValue{Key: "filter", Value: attribute.StringValue(string(filterRaw))})
}
span.SetAttributes(attributes...)

var duration *time.Duration
Expand All @@ -54,7 +60,19 @@ func (a *API) GetGroups(ctx context.Context, req *errorgroups.GetGroupsRequest)
Order: types.ErrorGroupsOrder(req.Order),
WithTotal: req.WithTotal,
}
groups, total, err := a.service.GetErrorGroups(ctx, request)

var (
groups []types.ErrorGroup
total uint64
err error
)

if req.Filter != nil && req.Filter.IsNew {
groups, total, err = a.service.GetNewErrorGroups(ctx, request)
} else {
groups, total, err = a.service.GetErrorGroups(ctx, request)
}

if err != nil {
return nil, grpcutil.ProcessError(err)
}
Expand Down
2 changes: 1 addition & 1 deletion internal/api/errorgroups/v1/grpc/get_hist.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import (
)

func (a *API) GetHist(ctx context.Context, req *errorgroups.GetHistRequest) (*errorgroups.GetHistResponse, error) {
ctx, span := tracing.StartSpan(ctx, "errorgroups_v1_get_groups")
ctx, span := tracing.StartSpan(ctx, "errorgroups_v1_get_hist")
defer span.End()

attributes := []attribute.KeyValue{
Expand Down
2 changes: 1 addition & 1 deletion internal/api/errorgroups/v1/grpc/get_releases.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
)

func (a *API) GetReleases(ctx context.Context, req *errorgroups.GetReleasesRequest) (*errorgroups.GetReleasesResponse, error) {
_, span := tracing.StartSpan(ctx, "errorgroups_v1_get_groups")
ctx, span := tracing.StartSpan(ctx, "errorgroups_v1_get_releases")
defer span.End()

attributes := []attribute.KeyValue{
Expand Down
2 changes: 1 addition & 1 deletion internal/api/errorgroups/v1/grpc/get_services.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
)

func (a *API) GetServices(ctx context.Context, req *errorgroups.GetServicesRequest) (*errorgroups.GetServicesResponse, error) {
_, span := tracing.StartSpan(ctx, "errorgroups_v1_get_groups")
ctx, span := tracing.StartSpan(ctx, "errorgroups_v1_get_services")
defer span.End()

attributes := []attribute.KeyValue{
Expand Down
Loading