Skip to content

Commit

Permalink
Merge pull request #112 from grafana/111-add-metrics-to-api
Browse files Browse the repository at this point in the history
add metrics to api
  • Loading branch information
szkiba authored Nov 17, 2024
2 parents c2067b0 + c44734b commit 4632c40
Show file tree
Hide file tree
Showing 6 changed files with 475 additions and 4 deletions.
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ After modifying registry schema ([registry.schema.json]), the [registry_gen.go]

```bash
curl -s -o docs/registry.schema.json https://raw.githubusercontent.com/grafana/k6-extension-registry/main/registry.schema.json
go-jsonschema --capitalization URL --capitalization OSS -p k6registry --only-models -o registry_gen.go docs/registry.schema.json
go-jsonschema --capitalization URL --capitalization JavaScript --capitalization OSS -p k6registry --only-models -o registry_gen.go docs/registry.schema.json
```

[registry.schema.json]: docs/registry.schema.json
Expand Down
10 changes: 7 additions & 3 deletions cmd/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,11 @@ func writeAPIGroupGlobal(registry k6registry.Registry, target string) error {
return err
}

return writeJSON(filepath.Join(target, "catalog.json"), k6registry.RegistryToCatalog(registry))
if err := writeJSON(filepath.Join(target, "catalog.json"), k6registry.RegistryToCatalog(registry)); err != nil {
return err
}

return writeJSON(filepath.Join(target, "metrics.json"), k6registry.CalculateMetrics(registry))
}

const gradesvg = `<svg xmlns="http://www.w3.org/2000/svg" width="17" height="20"><clipPath id="B"><rect width="17" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#B)"><path fill="%s" d="M0 0h17v20H0z"/><path fill="url(#A)" d="M0 0h17v20H0z"/></g><g text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110"><text x="85" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="70">%s</text><text x="85" y="140" transform="scale(.1)" fill="#fff" textLength="70">%s</text></g></svg>` //nolint:lll
Expand Down Expand Up @@ -352,9 +356,9 @@ func badgecolor(grade k6registry.Grade) badge.Color {
case k6registry.GradeC:
return "yellowgreen"
case k6registry.GradeD:
return "orange"
case k6registry.GradeE:
return "yellow"
case k6registry.GradeE:
return "orange"
case k6registry.GradeF:
return "red"
default:
Expand Down
191 changes: 191 additions & 0 deletions docs/registry.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,197 @@
"protocol"
]
]
},
"metrics": {
"type": "object",
"description": "Extension registry metrics.",
"properties": {
"registry_extension_count": {
"type": "integer",
"default": 0,
"description": "The total number of extensions."
},
"registry_tier_official_count": {
"type": "integer",
"default": 0,
"description": "Number of extensions in the 'official' tier."
},
"registry_tier_unofficial_count": {
"type": "integer",
"default": 0,
"description": "Number of unofficial extensions."
},
"registry_tier_partner_count": {
"type": "integer",
"default": 0,
"description": "Number of extensions in the 'partner' tier."
},
"registry_tier_community_count": {
"type": "integer",
"default": 0,
"description": "Number of extension in the community' tier."
},
"registry_type_javascript_count": {
"type": "integer",
"default": 0,
"description": "Number of JavaScript extension."
},
"registry_type_output_count": {
"type": "integer",
"default": 0,
"description": "Number of Output extension."
},
"registry_product_cloud_count": {
"type": "integer",
"default": 0,
"description": "Number of extensions available in Grafana Cloud k6."
},
"registry_product_oss_count": {
"type": "integer",
"default": 0,
"description": "Number of extensions available in Grafana k6."
},
"registry_product_synthetic_count": {
"type": "integer",
"default": 0,
"description": "Number of extensions available in Synthetic Monitoring."
},
"registry_grade_a_count": {
"type": "integer",
"default": 0,
"description": "Number of A-grade extensions."
},
"registry_grade_b_count": {
"type": "integer",
"default": 0,
"description": "Number of B-grade extensions."
},
"registry_grade_c_count": {
"type": "integer",
"default": 0,
"description": "Number of C-grade extensions."
},
"registry_grade_d_count": {
"type": "integer",
"default": 0,
"description": "Number of D-grade extensions."
},
"registry_grade_e_count": {
"type": "integer",
"default": 0,
"description": "Number of E-grade extensions."
},
"registry_grade_f_count": {
"type": "integer",
"default": 0,
"description": "Number of F-grade extensions."
},
"registry_cgo_count": {
"type": "integer",
"default": 0,
"description": "Number of extensions requiring cgo."
},
"registry_category_authentication_count": {
"type": "integer",
"default": 0,
"description": "Number of extensions in the 'authentication' category."
},
"registry_category_browser_count": {
"type": "integer",
"default": 0,
"description": "Number of extensions in the 'browser' category."
},
"registry_category_data_count": {
"type": "integer",
"default": 0,
"description": "Number of extensions in the 'data' category."
},
"registry_category_kubernetes_count": {
"type": "integer",
"default": 0,
"description": "Number of extensions in the 'kubernetes' category."
},
"registry_category_messaging_count": {
"type": "integer",
"default": 0,
"description": "Number of extensions in the 'messaging' category."
},
"registry_category_misc_count": {
"type": "integer",
"default": 0,
"description": "Number of extensions in the 'misc' category."
},
"registry_category_observability_count": {
"type": "integer",
"default": 0,
"description": "Number of extensions in the 'observability' category."
},
"registry_category_protocol_count": {
"type": "integer",
"default": 0,
"description": "Number of extensions in the 'protocol' category."
},
"registry_category_reporting_count": {
"type": "integer",
"default": 0,
"description": "Number of extensions in the 'reporting' category."
},
"registry_issue_module_count": {
"type": "integer",
"default": 0,
"description": "Number of extensions without valid go.mod."
},
"registry_issue_replace_count": {
"type": "integer",
"default": 0,
"description": "Number of extensions with replace directive in go.mod."
},
"registry_issue_readme_count": {
"type": "integer",
"default": 0,
"description": "Number of extensions without readme file."
},
"registry_issue_examples_count": {
"type": "integer",
"default": 0,
"description": "Number of extensions without examples directory."
},
"registry_issue_license_count": {
"type": "integer",
"default": 0,
"description": "Number of extensions without suitable OSS license."
},
"registry_issue_git_count": {
"type": "integer",
"default": 0,
"description": "Number of extensions without git workdir."
},
"registry_issue_versions_count": {
"type": "integer",
"default": 0,
"description": "Number of extensions without semantic versioning git tags."
},
"registry_issue_build_count": {
"type": "integer",
"default": 0,
"description": "Number of extensions not buildable with the latest k6 version."
},
"registry_issue_smoke_count": {
"type": "integer",
"default": 0,
"description": "Number of extensions without smoke test script."
},
"registry_issue_types_count": {
"type": "integer",
"default": 0,
"description": "Number of extensions without API declaration file."
},
"registry_issue_codeowners_count": {
"type": "integer",
"default": 0,
"description": "Number of extensions without CODEOWNERS file."
}
}
}
}
}
158 changes: 158 additions & 0 deletions metrics.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
package k6registry

import "strings"

// CalculateMetrics calculates registry metrics.
func CalculateMetrics(reg Registry) *Metrics {
const k6Module = "go.k6.io/k6"
m := new(Metrics)

for _, ext := range reg {
if ext.Module == k6Module {
continue
}

m.RegistryExtensionCount++

m.tier(ext.Tier)

if ext.Compliance != nil {
m.grade(ext.Compliance.Grade)
}

for _, prod := range ext.Products {
m.product(prod)
}

if len(ext.Products) == 0 {
m.RegistryProductOSSCount++
}

if len(ext.Imports) > 0 {
m.RegistryTypeJavaScriptCount++
}

if len(ext.Outputs) > 0 {
m.RegistryTypeOutputCount++
}

if strings.HasPrefix(ext.Module, "github.com/grafana/") && ext.Tier != TierOfficial {
m.RegistryTierUnofficialCount++
}

for _, cat := range ext.Categories {
m.category(cat)
}

if len(ext.Categories) == 0 {
m.RegistryCategoryMiscCount++
}

for _, issue := range ext.Compliance.Issues {
m.issue(issue)
}

if ext.Cgo {
m.RegistryCgoCount++
}
}

return m
}

func (m *Metrics) tier(tier Tier) {
switch tier {
case TierOfficial:
m.RegistryTierOfficialCount++
case TierPartner:
m.RegistryTierPartnerCount++
case TierCommunity:
fallthrough
default:
m.RegistryTierCommunityCount++
}
}

func (m *Metrics) grade(grade Grade) {
switch grade {
case GradeA:
m.RegistryGradeACount++
case GradeB:
m.RegistryGradeBCount++
case GradeC:
m.RegistryGradeCCount++
case GradeD:
m.RegistryGradeDCount++
case GradeE:
m.RegistryGradeECount++
case GradeF:
m.RegistryGradeFCount++
default:
}
}

func (m *Metrics) product(product Product) {
switch product {
case ProductCloud:
m.RegistryProductCloudCount++
case ProductSynthetic:
m.RegistryProductSyntheticCount++
case ProductOSS:
fallthrough
default:
m.RegistryProductOSSCount++
}
}

func (m *Metrics) category(category Category) {
switch category {
case CategoryAuthentication:
m.RegistryCategoryAuthenticationCount++
case CategoryBrowser:
m.RegistryCategoryBrowserCount++
case CategoryData:
m.RegistryCategoryDataCount++
case CategoryKubernetes:
m.RegistryCategoryKubernetesCount++
case CategoryMessaging:
m.RegistryCategoryMessagingCount++
case CategoryObservability:
m.RegistryCategoryObservabilityCount++
case CategoryProtocol:
m.RegistryCategoryProtocolCount++
case CategoryReporting:
m.RegistryCategoryReportingCount++
case CategoryMisc:
fallthrough
default:
m.RegistryCategoryMiscCount++
}
}

func (m *Metrics) issue(issue string) {
switch issue {
case "module":
m.RegistryIssueModuleCount++
case "replace":
m.RegistryIssueReplaceCount++
case "readme":
m.RegistryIssueReadmeCount++
case "examples":
m.RegistryIssueExamplesCount++
case "license":
m.RegistryIssueLicenseCount++
case "git":
m.RegistryIssueGitCount++
case "versions":
m.RegistryIssueVersionsCount++
case "build":
m.RegistryIssueBuildCount++
case "smoke":
m.RegistryIssueSmokeCount++
case "types":
m.RegistryIssueTypesCount++
case "codeowners":
m.RegistryIssueCodeownersCount++
default:
}
}
Loading

0 comments on commit 4632c40

Please sign in to comment.