Repository: census-instrumentation/opencensus-go
Pull request #300 (2018-01-07 18:19:48)

tag.Do: use tag.Map from provided context
  Fixes: #296


Patch:
diff --git a/README.md b/README.md
index 82a7667..c329a4e 100644
--- a/README.md
+++ b/README.md
@@ -45,11 +45,93 @@ Currently, only keys of type string are supported.
 Other types will be supported in the future.
 
 [embedmd]:# (tags.go stringKey)
-```go
-// Get a key to represent user OS.
-key, err := tag.NewKey("my.org/keys/user-os")
-if err != nil {
-	log.Fatal(err)
+```stringKey
+// Copyright 2017, OpenCensus Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package readme
+
+import (
+	"context"
+	"log"
+
+	"go.opencensus.io/tag"
+)
+
+func tagsExamples() {
+	ctx := context.Background()
+
+	// START stringKey
+	// Get a key to represent user OS.
+	key, err := tag.NewKey("my.org/keys/user-os")
+	if err != nil {
+		log.Fatal(err)
+	}
+	// END stringKey
+	_ = key
+
+	// START tagMap
+	osKey, err := tag.NewKey("my.org/keys/user-os")
+	if err != nil {
+		log.Fatal(err)
+	}
+	userIDKey, err := tag.NewKey("my.org/keys/user-id")
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	tagMap, err := tag.NewMap(ctx,
+		tag.Insert(osKey, "macOS-10.12.5"),
+		tag.Upsert(userIDKey, "cde36753ed"),
+	)
+	if err != nil {
+		log.Fatal(err)
+	}
+	// END tagMap
+
+	// START newContext
+	ctx = tag.NewContext(ctx, tagMap)
+	// END newContext
+
+	// START replaceTagMap
+	tagMap, err = tag.NewMap(ctx,
+		tag.Insert(key, "macOS-10.12.5"),
+		tag.Upsert(key, "macOS-10.12.7"),
+		tag.Upsert(userIDKey, "fff0989878"),
+	)
+	if err != nil {
+		log.Fatal(err)
+	}
+	ctx = tag.NewContext(ctx, tagMap)
+	// END replaceTagMap
+
+	// START profiler
+	tagMap, err = tag.NewMap(ctx,
+		tag.Insert(key, "macOS-10.12.5"),
+		tag.Upsert(key, "macOS-10.12.7"),
+		tag.Upsert(userIDKey, "fff0989878"),
+	)
+	if err != nil {
+		log.Fatal(err)
+	}
+	ctx = tag.NewContext(ctx, tagMap)
+	tag.Do(ctx, func(ctx context.Context) {
+		// Do work.
+		// When profiling is on, samples will be
+		// recorded with the key/values from the tag map.
+	})
+	// END profiler
 }
 ```
 
@@ -58,22 +140,93 @@ if err != nil {
 tag.Map is a map of tags. Package tags provide a builder to create tag maps.
 
 [embedmd]:# (tags.go tagMap)
-```go
-osKey, err := tag.NewKey("my.org/keys/user-os")
-if err != nil {
-	log.Fatal(err)
-}
-userIDKey, err := tag.NewKey("my.org/keys/user-id")
-if err != nil {
-	log.Fatal(err)
-}
-
-tagMap, err := tag.NewMap(ctx,
-	tag.Insert(osKey, "macOS-10.12.5"),
-	tag.Upsert(userIDKey, "cde36753ed"),
+```tagMap
+// Copyright 2017, OpenCensus Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package readme
+
+import (
+	"context"
+	"log"
+
+	"go.opencensus.io/tag"
 )
-if err != nil {
-	log.Fatal(err)
+
+func tagsExamples() {
+	ctx := context.Background()
+
+	// START stringKey
+	// Get a key to represent user OS.
+	key, err := tag.NewKey("my.org/keys/user-os")
+	if err != nil {
+		log.Fatal(err)
+	}
+	// END stringKey
+	_ = key
+
+	// START tagMap
+	osKey, err := tag.NewKey("my.org/keys/user-os")
+	if err != nil {
+		log.Fatal(err)
+	}
+	userIDKey, err := tag.NewKey("my.org/keys/user-id")
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	tagMap, err := tag.NewMap(ctx,
+		tag.Insert(osKey, "macOS-10.12.5"),
+		tag.Upsert(userIDKey, "cde36753ed"),
+	)
+	if err != nil {
+		log.Fatal(err)
+	}
+	// END tagMap
+
+	// START newContext
+	ctx = tag.NewContext(ctx, tagMap)
+	// END newContext
+
+	// START replaceTagMap
+	tagMap, err = tag.NewMap(ctx,
+		tag.Insert(key, "macOS-10.12.5"),
+		tag.Upsert(key, "macOS-10.12.7"),
+		tag.Upsert(userIDKey, "fff0989878"),
+	)
+	if err != nil {
+		log.Fatal(err)
+	}
+	ctx = tag.NewContext(ctx, tagMap)
+	// END replaceTagMap
+
+	// START profiler
+	tagMap, err = tag.NewMap(ctx,
+		tag.Insert(key, "macOS-10.12.5"),
+		tag.Upsert(key, "macOS-10.12.7"),
+		tag.Upsert(userIDKey, "fff0989878"),
+	)
+	if err != nil {
+		log.Fatal(err)
+	}
+	ctx = tag.NewContext(ctx, tagMap)
+	tag.Do(ctx, func(ctx context.Context) {
+		// Do work.
+		// When profiling is on, samples will be
+		// recorded with the key/values from the tag map.
+	})
+	// END profiler
 }
 ```
 
@@ -85,24 +238,188 @@ and put the tag map into the returned one.
 If there is already a tag map in the current context, it will be replaced.
 
 [embedmd]:# (tags.go newContext)
-```go
-ctx = tag.NewContext(ctx, tagMap)
+```newContext
+// Copyright 2017, OpenCensus Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package readme
+
+import (
+	"context"
+	"log"
+
+	"go.opencensus.io/tag"
+)
+
+func tagsExamples() {
+	ctx := context.Background()
+
+	// START stringKey
+	// Get a key to represent user OS.
+	key, err := tag.NewKey("my.org/keys/user-os")
+	if err != nil {
+		log.Fatal(err)
+	}
+	// END stringKey
+	_ = key
+
+	// START tagMap
+	osKey, err := tag.NewKey("my.org/keys/user-os")
+	if err != nil {
+		log.Fatal(err)
+	}
+	userIDKey, err := tag.NewKey("my.org/keys/user-id")
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	tagMap, err := tag.NewMap(ctx,
+		tag.Insert(osKey, "macOS-10.12.5"),
+		tag.Upsert(userIDKey, "cde36753ed"),
+	)
+	if err != nil {
+		log.Fatal(err)
+	}
+	// END tagMap
+
+	// START newContext
+	ctx = tag.NewContext(ctx, tagMap)
+	// END newContext
+
+	// START replaceTagMap
+	tagMap, err = tag.NewMap(ctx,
+		tag.Insert(key, "macOS-10.12.5"),
+		tag.Upsert(key, "macOS-10.12.7"),
+		tag.Upsert(userIDKey, "fff0989878"),
+	)
+	if err != nil {
+		log.Fatal(err)
+	}
+	ctx = tag.NewContext(ctx, tagMap)
+	// END replaceTagMap
+
+	// START profiler
+	tagMap, err = tag.NewMap(ctx,
+		tag.Insert(key, "macOS-10.12.5"),
+		tag.Upsert(key, "macOS-10.12.7"),
+		tag.Upsert(userIDKey, "fff0989878"),
+	)
+	if err != nil {
+		log.Fatal(err)
+	}
+	ctx = tag.NewContext(ctx, tagMap)
+	tag.Do(ctx, func(ctx context.Context) {
+		// Do work.
+		// When profiling is on, samples will be
+		// recorded with the key/values from the tag map.
+	})
+	// END profiler
+}
 ```
 
 In order to update an existing tag map, get the tag map from the current context,
 use NewMap and put the new tag map back to the context.
 
 [embedmd]:# (tags.go replaceTagMap)
-```go
-tagMap, err = tag.NewMap(ctx,
-	tag.Insert(key, "macOS-10.12.5"),
-	tag.Upsert(key, "macOS-10.12.7"),
-	tag.Upsert(userIDKey, "fff0989878"),
+```replaceTagMap
+// Copyright 2017, OpenCensus Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package readme
+
+import (
+	"context"
+	"log"
+
+	"go.opencensus.io/tag"
 )
-if err != nil {
-	log.Fatal(err)
+
+func tagsExamples() {
+	ctx := context.Background()
+
+	// START stringKey
+	// Get a key to represent user OS.
+	key, err := tag.NewKey("my.org/keys/user-os")
+	if err != nil {
+		log.Fatal(err)
+	}
+	// END stringKey
+	_ = key
+
+	// START tagMap
+	osKey, err := tag.NewKey("my.org/keys/user-os")
+	if err != nil {
+		log.Fatal(err)
+	}
+	userIDKey, err := tag.NewKey("my.org/keys/user-id")
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	tagMap, err := tag.NewMap(ctx,
+		tag.Insert(osKey, "macOS-10.12.5"),
+		tag.Upsert(userIDKey, "cde36753ed"),
+	)
+	if err != nil {
+		log.Fatal(err)
+	}
+	// END tagMap
+
+	// START newContext
+	ctx = tag.NewContext(ctx, tagMap)
+	// END newContext
+
+	// START replaceTagMap
+	tagMap, err = tag.NewMap(ctx,
+		tag.Insert(key, "macOS-10.12.5"),
+		tag.Upsert(key, "macOS-10.12.7"),
+		tag.Upsert(userIDKey, "fff0989878"),
+	)
+	if err != nil {
+		log.Fatal(err)
+	}
+	ctx = tag.NewContext(ctx, tagMap)
+	// END replaceTagMap
+
+	// START profiler
+	tagMap, err = tag.NewMap(ctx,
+		tag.Insert(key, "macOS-10.12.5"),
+		tag.Upsert(key, "macOS-10.12.7"),
+		tag.Upsert(userIDKey, "fff0989878"),
+	)
+	if err != nil {
+		log.Fatal(err)
+	}
+	ctx = tag.NewContext(ctx, tagMap)
+	tag.Do(ctx, func(ctx context.Context) {
+		// Do work.
+		// When profiling is on, samples will be
+		// recorded with the key/values from the tag map.
+	})
+	// END profiler
 }
-ctx = tag.NewContext(ctx, tagMap)
 ```
 
 
@@ -113,31 +430,428 @@ ctx = tag.NewContext(ctx, tagMap)
 Create and load measures with units:
 
 [embedmd]:# (stats.go measure)
-```go
-videoSize, err := stats.NewMeasureInt64("my.org/video_size", "processed video size", "MB")
-if err != nil {
-	log.Fatal(err)
+```measure
+// Copyright 2017, OpenCensus Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Package readme generates the README.
+package readme
+
+import (
+	"context"
+	"log"
+	"time"
+
+	"go.opencensus.io/stats"
+)
+
+// README.md is generated with the examples here by using embedmd.
+// For more details, see https://github.com/rakyll/embedmd.
+
+func statsExamples() {
+	ctx := context.Background()
+
+	// START measure
+	videoSize, err := stats.NewMeasureInt64("my.org/video_size", "processed video size", "MB")
+	if err != nil {
+		log.Fatal(err)
+	}
+	// END measure
+	_ = videoSize
+
+	// START findMeasure
+	m := stats.FindMeasure("my.org/video_size")
+	if m == nil {
+		log.Fatalln("measure not found")
+	}
+	// END findMeasure
+
+	_ = m
+
+	// START deleteMeasure
+	if err := stats.DeleteMeasure(m); err != nil {
+		log.Fatal(err)
+	}
+	// END deleteMeasure
+
+	// START aggs
+	distAgg := stats.DistributionAggregation([]float64{0, 1 << 32, 2 << 32, 3 << 32})
+	countAgg := stats.CountAggregation{}
+	sumAgg := stats.SumAggregation{}
+	meanAgg := stats.MeanAggregation{}
+	// END aggs
+
+	_, _, _, _ = distAgg, countAgg, sumAgg, meanAgg
+
+	// START windows
+	interval := stats.Interval{
+		Duration:  10 * time.Second,
+		Intervals: 5,
+	}
+
+	cum := stats.Cumulative{}
+	// END windows
+
+	_, _ = interval, cum
+
+	// START view
+	view, err := stats.NewView(
+		"my.org/video_size_distribution",
+		"distribution of processed video size over time",
+		nil,
+		videoSize,
+		distAgg,
+		cum,
+	)
+	if err != nil {
+		log.Fatalf("cannot create view: %v", err)
+	}
+	if err := stats.RegisterView(view); err != nil {
+		log.Fatal(err)
+	}
+	// END view
+
+	// START findView
+	v := stats.FindView("my.org/video_size_distribution")
+	if v == nil {
+		log.Fatalln("view not found")
+	}
+	// END findView
+
+	_ = v
+
+	// START unregisterView
+	if err = stats.UnregisterView(v); err != nil {
+		log.Fatal(err)
+	}
+	// END unregisterView
+
+	// START reportingPeriod
+	stats.SetReportingPeriod(5 * time.Second)
+	// END reportingPeriod
+
+	// START record
+	stats.Record(ctx, videoSize.M(102478))
+	// END record
+
+	// START subscribe
+	if err := view.Subscribe(); err != nil {
+		log.Fatal(err)
+	}
+	// END subscribe
+
+	// START registerExporter
+	// Register an exporter to be able to retrieve
+	// the data from the subscribed views.
+	stats.RegisterExporter(&exporter{})
+	// END registerExporter
+}
+
+// START exporter
+
+type exporter struct{}
+
+func (e *exporter) Export(vd *stats.ViewData) {
+	log.Println(vd)
 }
+
+// END exporter
 ```
 
 Retrieve measure by name:
 
 [embedmd]:# (stats.go findMeasure)
-```go
-m := stats.FindMeasure("my.org/video_size")
-if m == nil {
-	log.Fatalln("measure not found")
+```findMeasure
+// Copyright 2017, OpenCensus Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Package readme generates the README.
+package readme
+
+import (
+	"context"
+	"log"
+	"time"
+
+	"go.opencensus.io/stats"
+)
+
+// README.md is generated with the examples here by using embedmd.
+// For more details, see https://github.com/rakyll/embedmd.
+
+func statsExamples() {
+	ctx := context.Background()
+
+	// START measure
+	videoSize, err := stats.NewMeasureInt64("my.org/video_size", "processed video size", "MB")
+	if err != nil {
+		log.Fatal(err)
+	}
+	// END measure
+	_ = videoSize
+
+	// START findMeasure
+	m := stats.FindMeasure("my.org/video_size")
+	if m == nil {
+		log.Fatalln("measure not found")
+	}
+	// END findMeasure
+
+	_ = m
+
+	// START deleteMeasure
+	if err := stats.DeleteMeasure(m); err != nil {
+		log.Fatal(err)
+	}
+	// END deleteMeasure
+
+	// START aggs
+	distAgg := stats.DistributionAggregation([]float64{0, 1 << 32, 2 << 32, 3 << 32})
+	countAgg := stats.CountAggregation{}
+	sumAgg := stats.SumAggregation{}
+	meanAgg := stats.MeanAggregation{}
+	// END aggs
+
+	_, _, _, _ = distAgg, countAgg, sumAgg, meanAgg
+
+	// START windows
+	interval := stats.Interval{
+		Duration:  10 * time.Second,
+		Intervals: 5,
+	}
+
+	cum := stats.Cumulative{}
+	// END windows
+
+	_, _ = interval, cum
+
+	// START view
+	view, err := stats.NewView(
+		"my.org/video_size_distribution",
+		"distribution of processed video size over time",
+		nil,
+		videoSize,
+		distAgg,
+		cum,
+	)
+	if err != nil {
+		log.Fatalf("cannot create view: %v", err)
+	}
+	if err := stats.RegisterView(view); err != nil {
+		log.Fatal(err)
+	}
+	// END view
+
+	// START findView
+	v := stats.FindView("my.org/video_size_distribution")
+	if v == nil {
+		log.Fatalln("view not found")
+	}
+	// END findView
+
+	_ = v
+
+	// START unregisterView
+	if err = stats.UnregisterView(v); err != nil {
+		log.Fatal(err)
+	}
+	// END unregisterView
+
+	// START reportingPeriod
+	stats.SetReportingPeriod(5 * time.Second)
+	// END reportingPeriod
+
+	// START record
+	stats.Record(ctx, videoSize.M(102478))
+	// END record
+
+	// START subscribe
+	if err := view.Subscribe(); err != nil {
+		log.Fatal(err)
+	}
+	// END subscribe
+
+	// START registerExporter
+	// Register an exporter to be able to retrieve
+	// the data from the subscribed views.
+	stats.RegisterExporter(&exporter{})
+	// END registerExporter
+}
+
+// START exporter
+
+type exporter struct{}
+
+func (e *exporter) Export(vd *stats.ViewData) {
+	log.Println(vd)
 }
+
+// END exporter
 ```
 
 Delete measure (this can be useful when replacing a measure by
 another measure with the same name):
 
 [embedmd]:# (stats.go deleteMeasure)
-```go
-if err := stats.DeleteMeasure(m); err != nil {
-	log.Fatal(err)
+```deleteMeasure
+// Copyright 2017, OpenCensus Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Package readme generates the README.
+package readme
+
+import (
+	"context"
+	"log"
+	"time"
+
+	"go.opencensus.io/stats"
+)
+
+// README.md is generated with the examples here by using embedmd.
+// For more details, see https://github.com/rakyll/embedmd.
+
+func statsExamples() {
+	ctx := context.Background()
+
+	// START measure
+	videoSize, err := stats.NewMeasureInt64("my.org/video_size", "processed video size", "MB")
+	if err != nil {
+		log.Fatal(err)
+	}
+	// END measure
+	_ = videoSize
+
+	// START findMeasure
+	m := stats.FindMeasure("my.org/video_size")
+	if m == nil {
+		log.Fatalln("measure not found")
+	}
+	// END findMeasure
+
+	_ = m
+
+	// START deleteMeasure
+	if err := stats.DeleteMeasure(m); err != nil {
+		log.Fatal(err)
+	}
+	// END deleteMeasure
+
+	// START aggs
+	distAgg := stats.DistributionAggregation([]float64{0, 1 << 32, 2 << 32, 3 << 32})
+	countAgg := stats.CountAggregation{}
+	sumAgg := stats.SumAggregation{}
+	meanAgg := stats.MeanAggregation{}
+	// END aggs
+
+	_, _, _, _ = distAgg, countAgg, sumAgg, meanAgg
+
+	// START windows
+	interval := stats.Interval{
+		Duration:  10 * time.Second,
+		Intervals: 5,
+	}
+
+	cum := stats.Cumulative{}
+	// END windows
+
+	_, _ = interval, cum
+
+	// START view
+	view, err := stats.NewView(
+		"my.org/video_size_distribution",
+		"distribution of processed video size over time",
+		nil,
+		videoSize,
+		distAgg,
+		cum,
+	)
+	if err != nil {
+		log.Fatalf("cannot create view: %v", err)
+	}
+	if err := stats.RegisterView(view); err != nil {
+		log.Fatal(err)
+	}
+	// END view
+
+	// START findView
+	v := stats.FindView("my.org/video_size_distribution")
+	if v == nil {
+		log.Fatalln("view not found")
+	}
+	// END findView
+
+	_ = v
+
+	// START unregisterView
+	if err = stats.UnregisterView(v); err != nil {
+		log.Fatal(err)
+	}
+	// END unregisterView
+
+	// START reportingPeriod
+	stats.SetReportingPeriod(5 * time.Second)
+	// END reportingPeriod
+
+	// START record
+	stats.Record(ctx, videoSize.M(102478))
+	// END record
+
+	// START subscribe
+	if err := view.Subscribe(); err != nil {
+		log.Fatal(err)
+	}
+	// END subscribe
+
+	// START registerExporter
+	// Register an exporter to be able to retrieve
+	// the data from the subscribed views.
+	stats.RegisterExporter(&exporter{})
+	// END registerExporter
 }
+
+// START exporter
+
+type exporter struct{}
+
+func (e *exporter) Export(vd *stats.ViewData) {
+	log.Println(vd)
+}
+
+// END exporter
 ```
 However, it is an error to delete a Measure that's used by at least one View. The
 View using the Measure has to be unregistered first.
@@ -151,11 +865,143 @@ sum up all sample values. The MeanAggregation is used to calculate the mean of
 sample values.
 
 [embedmd]:# (stats.go aggs)
-```go
-distAgg := stats.DistributionAggregation([]float64{0, 1 << 32, 2 << 32, 3 << 32})
-countAgg := stats.CountAggregation{}
-sumAgg := stats.SumAggregation{}
-meanAgg := stats.MeanAggregation{}
+```aggs
+// Copyright 2017, OpenCensus Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Package readme generates the README.
+package readme
+
+import (
+	"context"
+	"log"
+	"time"
+
+	"go.opencensus.io/stats"
+)
+
+// README.md is generated with the examples here by using embedmd.
+// For more details, see https://github.com/rakyll/embedmd.
+
+func statsExamples() {
+	ctx := context.Background()
+
+	// START measure
+	videoSize, err := stats.NewMeasureInt64("my.org/video_size", "processed video size", "MB")
+	if err != nil {
+		log.Fatal(err)
+	}
+	// END measure
+	_ = videoSize
+
+	// START findMeasure
+	m := stats.FindMeasure("my.org/video_size")
+	if m == nil {
+		log.Fatalln("measure not found")
+	}
+	// END findMeasure
+
+	_ = m
+
+	// START deleteMeasure
+	if err := stats.DeleteMeasure(m); err != nil {
+		log.Fatal(err)
+	}
+	// END deleteMeasure
+
+	// START aggs
+	distAgg := stats.DistributionAggregation([]float64{0, 1 << 32, 2 << 32, 3 << 32})
+	countAgg := stats.CountAggregation{}
+	sumAgg := stats.SumAggregation{}
+	meanAgg := stats.MeanAggregation{}
+	// END aggs
+
+	_, _, _, _ = distAgg, countAgg, sumAgg, meanAgg
+
+	// START windows
+	interval := stats.Interval{
+		Duration:  10 * time.Second,
+		Intervals: 5,
+	}
+
+	cum := stats.Cumulative{}
+	// END windows
+
+	_, _ = interval, cum
+
+	// START view
+	view, err := stats.NewView(
+		"my.org/video_size_distribution",
+		"distribution of processed video size over time",
+		nil,
+		videoSize,
+		distAgg,
+		cum,
+	)
+	if err != nil {
+		log.Fatalf("cannot create view: %v", err)
+	}
+	if err := stats.RegisterView(view); err != nil {
+		log.Fatal(err)
+	}
+	// END view
+
+	// START findView
+	v := stats.FindView("my.org/video_size_distribution")
+	if v == nil {
+		log.Fatalln("view not found")
+	}
+	// END findView
+
+	_ = v
+
+	// START unregisterView
+	if err = stats.UnregisterView(v); err != nil {
+		log.Fatal(err)
+	}
+	// END unregisterView
+
+	// START reportingPeriod
+	stats.SetReportingPeriod(5 * time.Second)
+	// END reportingPeriod
+
+	// START record
+	stats.Record(ctx, videoSize.M(102478))
+	// END record
+
+	// START subscribe
+	if err := view.Subscribe(); err != nil {
+		log.Fatal(err)
+	}
+	// END subscribe
+
+	// START registerExporter
+	// Register an exporter to be able to retrieve
+	// the data from the subscribed views.
+	stats.RegisterExporter(&exporter{})
+	// END registerExporter
+}
+
+// START exporter
+
+type exporter struct{}
+
+func (e *exporter) Export(vd *stats.ViewData) {
+	log.Println(vd)
+}
+
+// END exporter
 ```
 
 ### Create an aggregation window
@@ -167,13 +1013,143 @@ Currently all aggregation types are compatible with all aggregation windows.
 Later we might provide aggregation types that are incompatible with some windows.
 
 [embedmd]:# (stats.go windows)
-```go
-interval := stats.Interval{
-	Duration:  10 * time.Second,
-	Intervals: 5,
+```windows
+// Copyright 2017, OpenCensus Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Package readme generates the README.
+package readme
+
+import (
+	"context"
+	"log"
+	"time"
+
+	"go.opencensus.io/stats"
+)
+
+// README.md is generated with the examples here by using embedmd.
+// For more details, see https://github.com/rakyll/embedmd.
+
+func statsExamples() {
+	ctx := context.Background()
+
+	// START measure
+	videoSize, err := stats.NewMeasureInt64("my.org/video_size", "processed video size", "MB")
+	if err != nil {
+		log.Fatal(err)
+	}
+	// END measure
+	_ = videoSize
+
+	// START findMeasure
+	m := stats.FindMeasure("my.org/video_size")
+	if m == nil {
+		log.Fatalln("measure not found")
+	}
+	// END findMeasure
+
+	_ = m
+
+	// START deleteMeasure
+	if err := stats.DeleteMeasure(m); err != nil {
+		log.Fatal(err)
+	}
+	// END deleteMeasure
+
+	// START aggs
+	distAgg := stats.DistributionAggregation([]float64{0, 1 << 32, 2 << 32, 3 << 32})
+	countAgg := stats.CountAggregation{}
+	sumAgg := stats.SumAggregation{}
+	meanAgg := stats.MeanAggregation{}
+	// END aggs
+
+	_, _, _, _ = distAgg, countAgg, sumAgg, meanAgg
+
+	// START windows
+	interval := stats.Interval{
+		Duration:  10 * time.Second,
+		Intervals: 5,
+	}
+
+	cum := stats.Cumulative{}
+	// END windows
+
+	_, _ = interval, cum
+
+	// START view
+	view, err := stats.NewView(
+		"my.org/video_size_distribution",
+		"distribution of processed video size over time",
+		nil,
+		videoSize,
+		distAgg,
+		cum,
+	)
+	if err != nil {
+		log.Fatalf("cannot create view: %v", err)
+	}
+	if err := stats.RegisterView(view); err != nil {
+		log.Fatal(err)
+	}
+	// END view
+
+	// START findView
+	v := stats.FindView("my.org/video_size_distribution")
+	if v == nil {
+		log.Fatalln("view not found")
+	}
+	// END findView
+
+	_ = v
+
+	// START unregisterView
+	if err = stats.UnregisterView(v); err != nil {
+		log.Fatal(err)
+	}
+	// END unregisterView
+
+	// START reportingPeriod
+	stats.SetReportingPeriod(5 * time.Second)
+	// END reportingPeriod
+
+	// START record
+	stats.Record(ctx, videoSize.M(102478))
+	// END record
+
+	// START subscribe
+	if err := view.Subscribe(); err != nil {
+		log.Fatal(err)
+	}
+	// END subscribe
+
+	// START registerExporter
+	// Register an exporter to be able to retrieve
+	// the data from the subscribed views.
+	stats.RegisterExporter(&exporter{})
+	// END registerExporter
 }
 
-cum := stats.Cumulative{}
+// START exporter
+
+type exporter struct{}
+
+func (e *exporter) Export(vd *stats.ViewData) {
+	log.Println(vd)
+}
+
+// END exporter
 ```
 
 ### Creating, registering and unregistering a view
@@ -181,40 +1157,427 @@ cum := stats.Cumulative{}
 Create and register a view:
 
 [embedmd]:# (stats.go view)
-```go
-view, err := stats.NewView(
-	"my.org/video_size_distribution",
-	"distribution of processed video size over time",
-	nil,
-	videoSize,
-	distAgg,
-	cum,
+```view
+// Copyright 2017, OpenCensus Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Package readme generates the README.
+package readme
+
+import (
+	"context"
+	"log"
+	"time"
+
+	"go.opencensus.io/stats"
 )
-if err != nil {
-	log.Fatalf("cannot create view: %v", err)
+
+// README.md is generated with the examples here by using embedmd.
+// For more details, see https://github.com/rakyll/embedmd.
+
+func statsExamples() {
+	ctx := context.Background()
+
+	// START measure
+	videoSize, err := stats.NewMeasureInt64("my.org/video_size", "processed video size", "MB")
+	if err != nil {
+		log.Fatal(err)
+	}
+	// END measure
+	_ = videoSize
+
+	// START findMeasure
+	m := stats.FindMeasure("my.org/video_size")
+	if m == nil {
+		log.Fatalln("measure not found")
+	}
+	// END findMeasure
+
+	_ = m
+
+	// START deleteMeasure
+	if err := stats.DeleteMeasure(m); err != nil {
+		log.Fatal(err)
+	}
+	// END deleteMeasure
+
+	// START aggs
+	distAgg := stats.DistributionAggregation([]float64{0, 1 << 32, 2 << 32, 3 << 32})
+	countAgg := stats.CountAggregation{}
+	sumAgg := stats.SumAggregation{}
+	meanAgg := stats.MeanAggregation{}
+	// END aggs
+
+	_, _, _, _ = distAgg, countAgg, sumAgg, meanAgg
+
+	// START windows
+	interval := stats.Interval{
+		Duration:  10 * time.Second,
+		Intervals: 5,
+	}
+
+	cum := stats.Cumulative{}
+	// END windows
+
+	_, _ = interval, cum
+
+	// START view
+	view, err := stats.NewView(
+		"my.org/video_size_distribution",
+		"distribution of processed video size over time",
+		nil,
+		videoSize,
+		distAgg,
+		cum,
+	)
+	if err != nil {
+		log.Fatalf("cannot create view: %v", err)
+	}
+	if err := stats.RegisterView(view); err != nil {
+		log.Fatal(err)
+	}
+	// END view
+
+	// START findView
+	v := stats.FindView("my.org/video_size_distribution")
+	if v == nil {
+		log.Fatalln("view not found")
+	}
+	// END findView
+
+	_ = v
+
+	// START unregisterView
+	if err = stats.UnregisterView(v); err != nil {
+		log.Fatal(err)
+	}
+	// END unregisterView
+
+	// START reportingPeriod
+	stats.SetReportingPeriod(5 * time.Second)
+	// END reportingPeriod
+
+	// START record
+	stats.Record(ctx, videoSize.M(102478))
+	// END record
+
+	// START subscribe
+	if err := view.Subscribe(); err != nil {
+		log.Fatal(err)
+	}
+	// END subscribe
+
+	// START registerExporter
+	// Register an exporter to be able to retrieve
+	// the data from the subscribed views.
+	stats.RegisterExporter(&exporter{})
+	// END registerExporter
 }
-if err := stats.RegisterView(view); err != nil {
-	log.Fatal(err)
+
+// START exporter
+
+type exporter struct{}
+
+func (e *exporter) Export(vd *stats.ViewData) {
+	log.Println(vd)
 }
+
+// END exporter
 ```
 
 Find view by name:
 
 [embedmd]:# (stats.go findView)
-```go
-v := stats.FindView("my.org/video_size_distribution")
-if v == nil {
-	log.Fatalln("view not found")
+```findView
+// Copyright 2017, OpenCensus Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Package readme generates the README.
+package readme
+
+import (
+	"context"
+	"log"
+	"time"
+
+	"go.opencensus.io/stats"
+)
+
+// README.md is generated with the examples here by using embedmd.
+// For more details, see https://github.com/rakyll/embedmd.
+
+func statsExamples() {
+	ctx := context.Background()
+
+	// START measure
+	videoSize, err := stats.NewMeasureInt64("my.org/video_size", "processed video size", "MB")
+	if err != nil {
+		log.Fatal(err)
+	}
+	// END measure
+	_ = videoSize
+
+	// START findMeasure
+	m := stats.FindMeasure("my.org/video_size")
+	if m == nil {
+		log.Fatalln("measure not found")
+	}
+	// END findMeasure
+
+	_ = m
+
+	// START deleteMeasure
+	if err := stats.DeleteMeasure(m); err != nil {
+		log.Fatal(err)
+	}
+	// END deleteMeasure
+
+	// START aggs
+	distAgg := stats.DistributionAggregation([]float64{0, 1 << 32, 2 << 32, 3 << 32})
+	countAgg := stats.CountAggregation{}
+	sumAgg := stats.SumAggregation{}
+	meanAgg := stats.MeanAggregation{}
+	// END aggs
+
+	_, _, _, _ = distAgg, countAgg, sumAgg, meanAgg
+
+	// START windows
+	interval := stats.Interval{
+		Duration:  10 * time.Second,
+		Intervals: 5,
+	}
+
+	cum := stats.Cumulative{}
+	// END windows
+
+	_, _ = interval, cum
+
+	// START view
+	view, err := stats.NewView(
+		"my.org/video_size_distribution",
+		"distribution of processed video size over time",
+		nil,
+		videoSize,
+		distAgg,
+		cum,
+	)
+	if err != nil {
+		log.Fatalf("cannot create view: %v", err)
+	}
+	if err := stats.RegisterView(view); err != nil {
+		log.Fatal(err)
+	}
+	// END view
+
+	// START findView
+	v := stats.FindView("my.org/video_size_distribution")
+	if v == nil {
+		log.Fatalln("view not found")
+	}
+	// END findView
+
+	_ = v
+
+	// START unregisterView
+	if err = stats.UnregisterView(v); err != nil {
+		log.Fatal(err)
+	}
+	// END unregisterView
+
+	// START reportingPeriod
+	stats.SetReportingPeriod(5 * time.Second)
+	// END reportingPeriod
+
+	// START record
+	stats.Record(ctx, videoSize.M(102478))
+	// END record
+
+	// START subscribe
+	if err := view.Subscribe(); err != nil {
+		log.Fatal(err)
+	}
+	// END subscribe
+
+	// START registerExporter
+	// Register an exporter to be able to retrieve
+	// the data from the subscribed views.
+	stats.RegisterExporter(&exporter{})
+	// END registerExporter
 }
+
+// START exporter
+
+type exporter struct{}
+
+func (e *exporter) Export(vd *stats.ViewData) {
+	log.Println(vd)
+}
+
+// END exporter
 ```
 
 Unregister view:
 
 [embedmd]:# (stats.go unregisterView)
-```go
-if err = stats.UnregisterView(v); err != nil {
-	log.Fatal(err)
+```unregisterView
+// Copyright 2017, OpenCensus Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Package readme generates the README.
+package readme
+
+import (
+	"context"
+	"log"
+	"time"
+
+	"go.opencensus.io/stats"
+)
+
+// README.md is generated with the examples here by using embedmd.
+// For more details, see https://github.com/rakyll/embedmd.
+
+func statsExamples() {
+	ctx := context.Background()
+
+	// START measure
+	videoSize, err := stats.NewMeasureInt64("my.org/video_size", "processed video size", "MB")
+	if err != nil {
+		log.Fatal(err)
+	}
+	// END measure
+	_ = videoSize
+
+	// START findMeasure
+	m := stats.FindMeasure("my.org/video_size")
+	if m == nil {
+		log.Fatalln("measure not found")
+	}
+	// END findMeasure
+
+	_ = m
+
+	// START deleteMeasure
+	if err := stats.DeleteMeasure(m); err != nil {
+		log.Fatal(err)
+	}
+	// END deleteMeasure
+
+	// START aggs
+	distAgg := stats.DistributionAggregation([]float64{0, 1 << 32, 2 << 32, 3 << 32})
+	countAgg := stats.CountAggregation{}
+	sumAgg := stats.SumAggregation{}
+	meanAgg := stats.MeanAggregation{}
+	// END aggs
+
+	_, _, _, _ = distAgg, countAgg, sumAgg, meanAgg
+
+	// START windows
+	interval := stats.Interval{
+		Duration:  10 * time.Second,
+		Intervals: 5,
+	}
+
+	cum := stats.Cumulative{}
+	// END windows
+
+	_, _ = interval, cum
+
+	// START view
+	view, err := stats.NewView(
+		"my.org/video_size_distribution",
+		"distribution of processed video size over time",
+		nil,
+		videoSize,
+		distAgg,
+		cum,
+	)
+	if err != nil {
+		log.Fatalf("cannot create view: %v", err)
+	}
+	if err := stats.RegisterView(view); err != nil {
+		log.Fatal(err)
+	}
+	// END view
+
+	// START findView
+	v := stats.FindView("my.org/video_size_distribution")
+	if v == nil {
+		log.Fatalln("view not found")
+	}
+	// END findView
+
+	_ = v
+
+	// START unregisterView
+	if err = stats.UnregisterView(v); err != nil {
+		log.Fatal(err)
+	}
+	// END unregisterView
+
+	// START reportingPeriod
+	stats.SetReportingPeriod(5 * time.Second)
+	// END reportingPeriod
+
+	// START record
+	stats.Record(ctx, videoSize.M(102478))
+	// END record
+
+	// START subscribe
+	if err := view.Subscribe(); err != nil {
+		log.Fatal(err)
+	}
+	// END subscribe
+
+	// START registerExporter
+	// Register an exporter to be able to retrieve
+	// the data from the subscribed views.
+	stats.RegisterExporter(&exporter{})
+	// END registerExporter
 }
+
+// START exporter
+
+type exporter struct{}
+
+func (e *exporter) Export(vd *stats.ViewData) {
+	log.Println(vd)
+}
+
+// END exporter
 ```
 
 Configure the default interval between reports of collected data.
@@ -223,8 +1586,143 @@ interval duration is 10 seconds. Trying to set an interval with
 a duration less than a certain minimum (maybe 1s) should have no effect.
 
 [embedmd]:# (stats.go reportingPeriod)
-```go
-stats.SetReportingPeriod(5 * time.Second)
+```reportingPeriod
+// Copyright 2017, OpenCensus Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Package readme generates the README.
+package readme
+
+import (
+	"context"
+	"log"
+	"time"
+
+	"go.opencensus.io/stats"
+)
+
+// README.md is generated with the examples here by using embedmd.
+// For more details, see https://github.com/rakyll/embedmd.
+
+func statsExamples() {
+	ctx := context.Background()
+
+	// START measure
+	videoSize, err := stats.NewMeasureInt64("my.org/video_size", "processed video size", "MB")
+	if err != nil {
+		log.Fatal(err)
+	}
+	// END measure
+	_ = videoSize
+
+	// START findMeasure
+	m := stats.FindMeasure("my.org/video_size")
+	if m == nil {
+		log.Fatalln("measure not found")
+	}
+	// END findMeasure
+
+	_ = m
+
+	// START deleteMeasure
+	if err := stats.DeleteMeasure(m); err != nil {
+		log.Fatal(err)
+	}
+	// END deleteMeasure
+
+	// START aggs
+	distAgg := stats.DistributionAggregation([]float64{0, 1 << 32, 2 << 32, 3 << 32})
+	countAgg := stats.CountAggregation{}
+	sumAgg := stats.SumAggregation{}
+	meanAgg := stats.MeanAggregation{}
+	// END aggs
+
+	_, _, _, _ = distAgg, countAgg, sumAgg, meanAgg
+
+	// START windows
+	interval := stats.Interval{
+		Duration:  10 * time.Second,
+		Intervals: 5,
+	}
+
+	cum := stats.Cumulative{}
+	// END windows
+
+	_, _ = interval, cum
+
+	// START view
+	view, err := stats.NewView(
+		"my.org/video_size_distribution",
+		"distribution of processed video size over time",
+		nil,
+		videoSize,
+		distAgg,
+		cum,
+	)
+	if err != nil {
+		log.Fatalf("cannot create view: %v", err)
+	}
+	if err := stats.RegisterView(view); err != nil {
+		log.Fatal(err)
+	}
+	// END view
+
+	// START findView
+	v := stats.FindView("my.org/video_size_distribution")
+	if v == nil {
+		log.Fatalln("view not found")
+	}
+	// END findView
+
+	_ = v
+
+	// START unregisterView
+	if err = stats.UnregisterView(v); err != nil {
+		log.Fatal(err)
+	}
+	// END unregisterView
+
+	// START reportingPeriod
+	stats.SetReportingPeriod(5 * time.Second)
+	// END reportingPeriod
+
+	// START record
+	stats.Record(ctx, videoSize.M(102478))
+	// END record
+
+	// START subscribe
+	if err := view.Subscribe(); err != nil {
+		log.Fatal(err)
+	}
+	// END subscribe
+
+	// START registerExporter
+	// Register an exporter to be able to retrieve
+	// the data from the subscribed views.
+	stats.RegisterExporter(&exporter{})
+	// END registerExporter
+}
+
+// START exporter
+
+type exporter struct{}
+
+func (e *exporter) Export(vd *stats.ViewData) {
+	log.Println(vd)
+}
+
+// END exporter
 ```
 
 ### Recording measurements
@@ -234,8 +1732,143 @@ and their registered views. Measurements are implicitly tagged with the
 tags in the context:
 
 [embedmd]:# (stats.go record)
-```go
-stats.Record(ctx, videoSize.M(102478))
+```record
+// Copyright 2017, OpenCensus Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Package readme generates the README.
+package readme
+
+import (
+	"context"
+	"log"
+	"time"
+
+	"go.opencensus.io/stats"
+)
+
+// README.md is generated with the examples here by using embedmd.
+// For more details, see https://github.com/rakyll/embedmd.
+
+func statsExamples() {
+	ctx := context.Background()
+
+	// START measure
+	videoSize, err := stats.NewMeasureInt64("my.org/video_size", "processed video size", "MB")
+	if err != nil {
+		log.Fatal(err)
+	}
+	// END measure
+	_ = videoSize
+
+	// START findMeasure
+	m := stats.FindMeasure("my.org/video_size")
+	if m == nil {
+		log.Fatalln("measure not found")
+	}
+	// END findMeasure
+
+	_ = m
+
+	// START deleteMeasure
+	if err := stats.DeleteMeasure(m); err != nil {
+		log.Fatal(err)
+	}
+	// END deleteMeasure
+
+	// START aggs
+	distAgg := stats.DistributionAggregation([]float64{0, 1 << 32, 2 << 32, 3 << 32})
+	countAgg := stats.CountAggregation{}
+	sumAgg := stats.SumAggregation{}
+	meanAgg := stats.MeanAggregation{}
+	// END aggs
+
+	_, _, _, _ = distAgg, countAgg, sumAgg, meanAgg
+
+	// START windows
+	interval := stats.Interval{
+		Duration:  10 * time.Second,
+		Intervals: 5,
+	}
+
+	cum := stats.Cumulative{}
+	// END windows
+
+	_, _ = interval, cum
+
+	// START view
+	view, err := stats.NewView(
+		"my.org/video_size_distribution",
+		"distribution of processed video size over time",
+		nil,
+		videoSize,
+		distAgg,
+		cum,
+	)
+	if err != nil {
+		log.Fatalf("cannot create view: %v", err)
+	}
+	if err := stats.RegisterView(view); err != nil {
+		log.Fatal(err)
+	}
+	// END view
+
+	// START findView
+	v := stats.FindView("my.org/video_size_distribution")
+	if v == nil {
+		log.Fatalln("view not found")
+	}
+	// END findView
+
+	_ = v
+
+	// START unregisterView
+	if err = stats.UnregisterView(v); err != nil {
+		log.Fatal(err)
+	}
+	// END unregisterView
+
+	// START reportingPeriod
+	stats.SetReportingPeriod(5 * time.Second)
+	// END reportingPeriod
+
+	// START record
+	stats.Record(ctx, videoSize.M(102478))
+	// END record
+
+	// START subscribe
+	if err := view.Subscribe(); err != nil {
+		log.Fatal(err)
+	}
+	// END subscribe
+
+	// START registerExporter
+	// Register an exporter to be able to retrieve
+	// the data from the subscribed views.
+	stats.RegisterExporter(&exporter{})
+	// END registerExporter
+}
+
+// START exporter
+
+type exporter struct{}
+
+func (e *exporter) Export(vd *stats.ViewData) {
+	log.Println(vd)
+}
+
+// END exporter
 ```
 
 ### Retrieving collected data for a view
@@ -243,25 +1876,419 @@ stats.Record(ctx, videoSize.M(102478))
 Users need to subscribe to a view in order to retrieve collected data.
 
 [embedmd]:# (stats.go subscribe)
-```go
-if err := view.Subscribe(); err != nil {
-	log.Fatal(err)
+```subscribe
+// Copyright 2017, OpenCensus Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Package readme generates the README.
+package readme
+
+import (
+	"context"
+	"log"
+	"time"
+
+	"go.opencensus.io/stats"
+)
+
+// README.md is generated with the examples here by using embedmd.
+// For more details, see https://github.com/rakyll/embedmd.
+
+func statsExamples() {
+	ctx := context.Background()
+
+	// START measure
+	videoSize, err := stats.NewMeasureInt64("my.org/video_size", "processed video size", "MB")
+	if err != nil {
+		log.Fatal(err)
+	}
+	// END measure
+	_ = videoSize
+
+	// START findMeasure
+	m := stats.FindMeasure("my.org/video_size")
+	if m == nil {
+		log.Fatalln("measure not found")
+	}
+	// END findMeasure
+
+	_ = m
+
+	// START deleteMeasure
+	if err := stats.DeleteMeasure(m); err != nil {
+		log.Fatal(err)
+	}
+	// END deleteMeasure
+
+	// START aggs
+	distAgg := stats.DistributionAggregation([]float64{0, 1 << 32, 2 << 32, 3 << 32})
+	countAgg := stats.CountAggregation{}
+	sumAgg := stats.SumAggregation{}
+	meanAgg := stats.MeanAggregation{}
+	// END aggs
+
+	_, _, _, _ = distAgg, countAgg, sumAgg, meanAgg
+
+	// START windows
+	interval := stats.Interval{
+		Duration:  10 * time.Second,
+		Intervals: 5,
+	}
+
+	cum := stats.Cumulative{}
+	// END windows
+
+	_, _ = interval, cum
+
+	// START view
+	view, err := stats.NewView(
+		"my.org/video_size_distribution",
+		"distribution of processed video size over time",
+		nil,
+		videoSize,
+		distAgg,
+		cum,
+	)
+	if err != nil {
+		log.Fatalf("cannot create view: %v", err)
+	}
+	if err := stats.RegisterView(view); err != nil {
+		log.Fatal(err)
+	}
+	// END view
+
+	// START findView
+	v := stats.FindView("my.org/video_size_distribution")
+	if v == nil {
+		log.Fatalln("view not found")
+	}
+	// END findView
+
+	_ = v
+
+	// START unregisterView
+	if err = stats.UnregisterView(v); err != nil {
+		log.Fatal(err)
+	}
+	// END unregisterView
+
+	// START reportingPeriod
+	stats.SetReportingPeriod(5 * time.Second)
+	// END reportingPeriod
+
+	// START record
+	stats.Record(ctx, videoSize.M(102478))
+	// END record
+
+	// START subscribe
+	if err := view.Subscribe(); err != nil {
+		log.Fatal(err)
+	}
+	// END subscribe
+
+	// START registerExporter
+	// Register an exporter to be able to retrieve
+	// the data from the subscribed views.
+	stats.RegisterExporter(&exporter{})
+	// END registerExporter
+}
+
+// START exporter
+
+type exporter struct{}
+
+func (e *exporter) Export(vd *stats.ViewData) {
+	log.Println(vd)
 }
+
+// END exporter
 ```
 
 Subscribed views' data will be exported via the registered exporters.
 
 [embedmd]:# (stats.go registerExporter)
-```go
-// Register an exporter to be able to retrieve
-// the data from the subscribed views.
-stats.RegisterExporter(&exporter{})
+```registerExporter
+// Copyright 2017, OpenCensus Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Package readme generates the README.
+package readme
+
+import (
+	"context"
+	"log"
+	"time"
+
+	"go.opencensus.io/stats"
+)
+
+// README.md is generated with the examples here by using embedmd.
+// For more details, see https://github.com/rakyll/embedmd.
+
+func statsExamples() {
+	ctx := context.Background()
+
+	// START measure
+	videoSize, err := stats.NewMeasureInt64("my.org/video_size", "processed video size", "MB")
+	if err != nil {
+		log.Fatal(err)
+	}
+	// END measure
+	_ = videoSize
+
+	// START findMeasure
+	m := stats.FindMeasure("my.org/video_size")
+	if m == nil {
+		log.Fatalln("measure not found")
+	}
+	// END findMeasure
+
+	_ = m
+
+	// START deleteMeasure
+	if err := stats.DeleteMeasure(m); err != nil {
+		log.Fatal(err)
+	}
+	// END deleteMeasure
+
+	// START aggs
+	distAgg := stats.DistributionAggregation([]float64{0, 1 << 32, 2 << 32, 3 << 32})
+	countAgg := stats.CountAggregation{}
+	sumAgg := stats.SumAggregation{}
+	meanAgg := stats.MeanAggregation{}
+	// END aggs
+
+	_, _, _, _ = distAgg, countAgg, sumAgg, meanAgg
+
+	// START windows
+	interval := stats.Interval{
+		Duration:  10 * time.Second,
+		Intervals: 5,
+	}
+
+	cum := stats.Cumulative{}
+	// END windows
+
+	_, _ = interval, cum
+
+	// START view
+	view, err := stats.NewView(
+		"my.org/video_size_distribution",
+		"distribution of processed video size over time",
+		nil,
+		videoSize,
+		distAgg,
+		cum,
+	)
+	if err != nil {
+		log.Fatalf("cannot create view: %v", err)
+	}
+	if err := stats.RegisterView(view); err != nil {
+		log.Fatal(err)
+	}
+	// END view
+
+	// START findView
+	v := stats.FindView("my.org/video_size_distribution")
+	if v == nil {
+		log.Fatalln("view not found")
+	}
+	// END findView
+
+	_ = v
+
+	// START unregisterView
+	if err = stats.UnregisterView(v); err != nil {
+		log.Fatal(err)
+	}
+	// END unregisterView
+
+	// START reportingPeriod
+	stats.SetReportingPeriod(5 * time.Second)
+	// END reportingPeriod
+
+	// START record
+	stats.Record(ctx, videoSize.M(102478))
+	// END record
+
+	// START subscribe
+	if err := view.Subscribe(); err != nil {
+		log.Fatal(err)
+	}
+	// END subscribe
+
+	// START registerExporter
+	// Register an exporter to be able to retrieve
+	// the data from the subscribed views.
+	stats.RegisterExporter(&exporter{})
+	// END registerExporter
+}
+
+// START exporter
+
+type exporter struct{}
+
+func (e *exporter) Export(vd *stats.ViewData) {
+	log.Println(vd)
+}
+
+// END exporter
 ```
 
 An example logger exporter is below:
 
 [embedmd]:# (stats.go exporter)
-```go
+```exporter
+// Copyright 2017, OpenCensus Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Package readme generates the README.
+package readme
+
+import (
+	"context"
+	"log"
+	"time"
+
+	"go.opencensus.io/stats"
+)
+
+// README.md is generated with the examples here by using embedmd.
+// For more details, see https://github.com/rakyll/embedmd.
+
+func statsExamples() {
+	ctx := context.Background()
+
+	// START measure
+	videoSize, err := stats.NewMeasureInt64("my.org/video_size", "processed video size", "MB")
+	if err != nil {
+		log.Fatal(err)
+	}
+	// END measure
+	_ = videoSize
+
+	// START findMeasure
+	m := stats.FindMeasure("my.org/video_size")
+	if m == nil {
+		log.Fatalln("measure not found")
+	}
+	// END findMeasure
+
+	_ = m
+
+	// START deleteMeasure
+	if err := stats.DeleteMeasure(m); err != nil {
+		log.Fatal(err)
+	}
+	// END deleteMeasure
+
+	// START aggs
+	distAgg := stats.DistributionAggregation([]float64{0, 1 << 32, 2 << 32, 3 << 32})
+	countAgg := stats.CountAggregation{}
+	sumAgg := stats.SumAggregation{}
+	meanAgg := stats.MeanAggregation{}
+	// END aggs
+
+	_, _, _, _ = distAgg, countAgg, sumAgg, meanAgg
+
+	// START windows
+	interval := stats.Interval{
+		Duration:  10 * time.Second,
+		Intervals: 5,
+	}
+
+	cum := stats.Cumulative{}
+	// END windows
+
+	_, _ = interval, cum
+
+	// START view
+	view, err := stats.NewView(
+		"my.org/video_size_distribution",
+		"distribution of processed video size over time",
+		nil,
+		videoSize,
+		distAgg,
+		cum,
+	)
+	if err != nil {
+		log.Fatalf("cannot create view: %v", err)
+	}
+	if err := stats.RegisterView(view); err != nil {
+		log.Fatal(err)
+	}
+	// END view
+
+	// START findView
+	v := stats.FindView("my.org/video_size_distribution")
+	if v == nil {
+		log.Fatalln("view not found")
+	}
+	// END findView
+
+	_ = v
+
+	// START unregisterView
+	if err = stats.UnregisterView(v); err != nil {
+		log.Fatal(err)
+	}
+	// END unregisterView
+
+	// START reportingPeriod
+	stats.SetReportingPeriod(5 * time.Second)
+	// END reportingPeriod
+
+	// START record
+	stats.Record(ctx, videoSize.M(102478))
+	// END record
+
+	// START subscribe
+	if err := view.Subscribe(); err != nil {
+		log.Fatal(err)
+	}
+	// END subscribe
+
+	// START registerExporter
+	// Register an exporter to be able to retrieve
+	// the data from the subscribed views.
+	stats.RegisterExporter(&exporter{})
+	// END registerExporter
+}
+
+// START exporter
 
 type exporter struct{}
 
@@ -269,6 +2296,7 @@ func (e *exporter) Export(vd *stats.ViewData) {
 	log.Println(vd)
 }
 
+// END exporter
 ```
 
 ## Traces
@@ -276,9 +2304,37 @@ func (e *exporter) Export(vd *stats.ViewData) {
 ### Starting and ending a span
 
 [embedmd]:# (trace.go startend)
-```go
-ctx = trace.StartSpan(ctx, "your choice of name")
-defer trace.EndSpan(ctx)
+```startend
+// Copyright 2017, OpenCensus Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package readme
+
+import (
+	"context"
+
+	"go.opencensus.io/trace"
+)
+
+func traceExamples() {
+	ctx := context.Background()
+
+	// START startend
+	ctx = trace.StartSpan(ctx, "your choice of name")
+	defer trace.EndSpan(ctx)
+	// END startend
+}
 ```
 
 More tracing examples are coming soon...
@@ -289,20 +2345,94 @@ OpenCensus tags can be applied as profiler labels
 for users who are on Go 1.9 and above.
 
 [embedmd]:# (tags.go profiler)
-```go
-tagMap, err = tag.NewMap(ctx,
-	tag.Insert(key, "macOS-10.12.5"),
-	tag.Upsert(key, "macOS-10.12.7"),
-	tag.Upsert(userIDKey, "fff0989878"),
+```profiler
+// Copyright 2017, OpenCensus Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package readme
+
+import (
+	"context"
+	"log"
+
+	"go.opencensus.io/tag"
 )
-if err != nil {
-	log.Fatal(err)
-}
-tag.Do(ctx, tagMap, func(ctx context.Context) {
-	// Do work.
-	// When profiling is on, samples will be
-	// recorded with the key/values from the tag map.
-})
+
+func tagsExamples() {
+	ctx := context.Background()
+
+	// START stringKey
+	// Get a key to represent user OS.
+	key, err := tag.NewKey("my.org/keys/user-os")
+	if err != nil {
+		log.Fatal(err)
+	}
+	// END stringKey
+	_ = key
+
+	// START tagMap
+	osKey, err := tag.NewKey("my.org/keys/user-os")
+	if err != nil {
+		log.Fatal(err)
+	}
+	userIDKey, err := tag.NewKey("my.org/keys/user-id")
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	tagMap, err := tag.NewMap(ctx,
+		tag.Insert(osKey, "macOS-10.12.5"),
+		tag.Upsert(userIDKey, "cde36753ed"),
+	)
+	if err != nil {
+		log.Fatal(err)
+	}
+	// END tagMap
+
+	// START newContext
+	ctx = tag.NewContext(ctx, tagMap)
+	// END newContext
+
+	// START replaceTagMap
+	tagMap, err = tag.NewMap(ctx,
+		tag.Insert(key, "macOS-10.12.5"),
+		tag.Upsert(key, "macOS-10.12.7"),
+		tag.Upsert(userIDKey, "fff0989878"),
+	)
+	if err != nil {
+		log.Fatal(err)
+	}
+	ctx = tag.NewContext(ctx, tagMap)
+	// END replaceTagMap
+
+	// START profiler
+	tagMap, err = tag.NewMap(ctx,
+		tag.Insert(key, "macOS-10.12.5"),
+		tag.Upsert(key, "macOS-10.12.7"),
+		tag.Upsert(userIDKey, "fff0989878"),
+	)
+	if err != nil {
+		log.Fatal(err)
+	}
+	ctx = tag.NewContext(ctx, tagMap)
+	tag.Do(ctx, func(ctx context.Context) {
+		// Do work.
+		// When profiling is on, samples will be
+		// recorded with the key/values from the tag map.
+	})
+	// END profiler
+}
 ```
 
 A screenshot of the CPU profile from the program above:
diff --git a/internal/readme/tags.go b/internal/readme/tags.go
index b1140a2..2fff06c 100644
--- a/internal/readme/tags.go
+++ b/internal/readme/tags.go
@@ -77,7 +77,8 @@ func tagsExamples() {
 	if err != nil {
 		log.Fatal(err)
 	}
-	tag.Do(ctx, tagMap, func(ctx context.Context) {
+	ctx = tag.NewContext(ctx, tagMap)
+	tag.Do(ctx, func(ctx context.Context) {
 		// Do work.
 		// When profiling is on, samples will be
 		// recorded with the key/values from the tag map.
diff --git a/tag/map.go b/tag/map.go
index 55eb641..56d2c7d 100644
--- a/tag/map.go
+++ b/tag/map.go
@@ -169,14 +169,16 @@ func NewMap(ctx context.Context, mutator ...Mutator) (*Map, error) {
 	return m, nil
 }
 
-// Do is similar to pprof.Do.
+// Do is similar to pprof.Do: a convenience for installing the tags
+// from the context as Go profiler labels. This allows you to
+// correlated runtime profiling with stats.
 //
 // It converts the key/values from the given map to Go profiler labels
 // and calls pprof.Do.
 //
 // Do is going to do nothing if your Go version is below 1.9.
-func Do(ctx context.Context, m *Map, f func(ctx context.Context)) {
-	do(ctx, m, f)
+func Do(ctx context.Context, f func(ctx context.Context)) {
+	do(ctx, f)
 }
 
 type mutator struct {
diff --git a/tag/profile_19.go b/tag/profile_19.go
index 26aaf34..f81cd0b 100644
--- a/tag/profile_19.go
+++ b/tag/profile_19.go
@@ -21,7 +21,8 @@ import (
 	"runtime/pprof"
 )
 
-func do(ctx context.Context, m *Map, f func(ctx context.Context)) {
+func do(ctx context.Context, f func(ctx context.Context)) {
+	m := FromContext(ctx)
 	keyvals := make([]string, 0, 2*len(m.m))
 	for k, v := range m.m {
 		keyvals = append(keyvals, k.Name(), v)
diff --git a/tag/profile_not19.go b/tag/profile_not19.go
index cf24327..83adbce 100644
--- a/tag/profile_not19.go
+++ b/tag/profile_not19.go
@@ -18,6 +18,6 @@ package tag
 
 import "context"
 
-func do(ctx context.Context, m *Map, f func(ctx context.Context)) {
+func do(ctx context.Context, f func(ctx context.Context)) {
 	f(ctx)
 }


Test patch:
diff --git a/tag/example_test.go b/tag/example_test.go
index 0efe17f..d7b52be 100644
--- a/tag/example_test.go
+++ b/tag/example_test.go
@@ -82,3 +82,17 @@ func ExampleFromContext() {
 
 	_ = tagMap // use the tag map
 }
+
+func ExampleDo() {
+	tagMap, err := tag.NewMap(ctx,
+		tag.Insert(key, "macOS-10.12.5"),
+		tag.Upsert(key, "macOS-10.12.7"),
+	)
+	if err != nil {
+		log.Fatal(err)
+	}
+	ctx = tag.NewContext(ctx, tagMap)
+	tag.Do(ctx, func(ctx context.Context) {
+		_ = ctx // use context
+	})
+}
diff --git a/tag/map_test.go b/tag/map_test.go
index 9d0d66b..c15b371 100644
--- a/tag/map_test.go
+++ b/tag/map_test.go
@@ -40,17 +40,20 @@ func TestContext(t *testing.T) {
 	}
 }
 
-func TestDoFunctionCalled(t *testing.T) {
-	ctx := context.Background()
-	want, _ := NewMap(ctx)
-	called := false
-
-	Do(ctx, want, func(ctx context.Context) {
-			called = true
+func TestDo(t *testing.T) {
+	k1, _ := NewKey("k1")
+	k2, _ := NewKey("k2")
+	want, _ := NewMap(context.Background(),
+		Insert(k1, "v1"),
+		Insert(k2, "v2"),
+	)
+	ctx := NewContext(context.Background(), want)
+	var got *Map
+	Do(ctx, func(ctx context.Context) {
+		got = FromContext(ctx)
 	})
-
-	if !called {
-		t.Errorf("function should be called")
+	if !reflect.DeepEqual(got, want) {
+		t.Errorf("Map = %#v; want %#v", got, want)
 	}
 }