diff --git a/cmd/frontend/main.go b/cmd/frontend/main.go
index c3541cd..934554d 100644
--- a/cmd/frontend/main.go
+++ b/cmd/frontend/main.go
@@ -192,6 +192,7 @@
middleware.CacheErrorCount,
middleware.CacheLatency,
middleware.QuotaResultCount,
+ dcensus.CodeWikiClickCountView,
)
if err := dcensus.Init(cfg, views...); err != nil {
log.Fatal(ctx, err)
diff --git a/internal/dcensus/dcensus.go b/internal/dcensus/dcensus.go
index 1447a0d..c525e4e 100644
--- a/internal/dcensus/dcensus.go
+++ b/internal/dcensus/dcensus.go
@@ -241,6 +241,22 @@
}
)
+var (
+ // KeyReferrer is a tag key for the referrer URL.
+ KeyReferrer = tag.MustNewKey("referrer")
+ // KeyTargetURL is a tag key for the target URL.
+ KeyTargetURL = tag.MustNewKey("target_url")
+
+ CodeWikiClickCount = stats.Int64("go-discovery/frontend_codewiki_clicks", "Codewiki link clicks", stats.UnitDimensionless)
+ CodeWikiClickCountView = &view.View{
+ Name: "go-discovery/frontend/codewiki_clicks",
+ Description: "Count of codewiki link clicks",
+ TagKeys: []tag.Key{KeyReferrer, KeyTargetURL},
+ Measure: CodeWikiClickCount,
+ Aggregation: view.Count(),
+ }
+)
+
// RecordWithTag is a convenience function for recording a single measurement with a single tag.
func RecordWithTag(ctx context.Context, key tag.Key, val string, m stats.Measurement) {
stats.RecordWithTags(ctx, []tag.Mutator{tag.Upsert(key, val)}, m)
diff --git a/internal/frontend/server.go b/internal/frontend/server.go
index e15f929..44e52fc 100644
--- a/internal/frontend/server.go
+++ b/internal/frontend/server.go
@@ -20,8 +20,11 @@
"time"
"github.com/google/safehtml/template"
+ ocstats "go.opencensus.io/stats"
+ "go.opencensus.io/tag"
"golang.org/x/pkgsite/internal"
"golang.org/x/pkgsite/internal/config"
+ "golang.org/x/pkgsite/internal/dcensus"
"golang.org/x/pkgsite/internal/derrors"
"golang.org/x/pkgsite/internal/experiment"
pagepkg "golang.org/x/pkgsite/internal/frontend/page"
@@ -141,6 +144,21 @@
return s, nil
}
+func (s *Server) handleCodeWikiRedirect(w http.ResponseWriter, r *http.Request) {
+ url := r.FormValue("url")
+ if url == "" {
+ http.Error(w, "missing url", http.StatusBadRequest)
+ return
+ }
+ ctx := r.Context()
+ mutators := []tag.Mutator{
+ tag.Upsert(dcensus.KeyTargetURL, url),
+ tag.Upsert(dcensus.KeyReferrer, r.Header.Get("Referer")),
+ }
+ ocstats.RecordWithTags(ctx, mutators, dcensus.CodeWikiClickCount.M(1))
+ http.Redirect(w, r, url, http.StatusFound)
+}
+
// A Cacher is used to create request caches for http handlers.
type Cacher interface {
// Cache returns a new middleware that caches every request.
@@ -211,6 +229,7 @@
// (This is what golang.org/C does.)
http.Redirect(w, r, "/cmd/cgo", http.StatusMovedPermanently)
}))
+ handle("GET /codewiki", http.HandlerFunc(s.handleCodeWikiRedirect))
handle("GET /golang.org/x", s.staticPageHandler("subrepo", "Sub-repositories"))
handle("GET /files/", http.StripPrefix("/files", s.fileMux))
handle("GET /vuln/", vulnHandler)
diff --git a/static/frontend/unit/main/_meta.tmpl b/static/frontend/unit/main/_meta.tmpl
index 8e32eb2..5b3a8dd 100644
--- a/static/frontend/unit/main/_meta.tmpl
+++ b/static/frontend/unit/main/_meta.tmpl
@@ -42,7 +42,7 @@
{{end}}
{{with .CodeWikiURL}}
<li>
- <a href="{{.}}" title="View this repo on Code Wiki"
+ <a href="/codewiki?url={{.}}" title="View this repo on Code Wiki"
target="_blank" rel="noopener" data-test-id="meta-link-codewiki">
<img class="go-Icon" src="/static/shared/icon/codewiki-logo.svg"
alt="Code Wiki Logo" />