mirror of
https://github.com/marcel-dempers/docker-development-youtube-series.git
synced 2025-06-06 17:01:30 +00:00
Merge branch 'master' into linkerd-jaeger
This commit is contained in:
commit
9223348c32
17
golang/introduction/part-4.commandline/dockerfile
Normal file
17
golang/introduction/part-4.commandline/dockerfile
Normal file
@ -0,0 +1,17 @@
|
||||
FROM golang:1.15-alpine as dev
|
||||
|
||||
WORKDIR /work
|
||||
|
||||
# FROM golang:1.15-alpine as build
|
||||
|
||||
# WORKDIR /videos
|
||||
# COPY ./videos/* /videos/
|
||||
# RUN go build -o videos
|
||||
|
||||
|
||||
# FROM alpine as runtime
|
||||
# COPY --from=build /videos/videos /usr/local/bin/videos
|
||||
# COPY ./videos/videos.json /
|
||||
# COPY run.sh /
|
||||
# RUN chmod +x /run.sh
|
||||
# ENTRYPOINT [ "./run.sh" ]
|
416
golang/introduction/part-4.commandline/readme.md
Normal file
416
golang/introduction/part-4.commandline/readme.md
Normal file
@ -0,0 +1,416 @@
|
||||
# Introduction to Go: Command Line
|
||||
|
||||
Command line apps are a fundamental part of software development <br/>
|
||||
|
||||
Go has a built in Commandline parser package. The package can be found [here](https://golang.org/pkg/flag/) <br/>
|
||||
We simply have to import the `flag` package:
|
||||
|
||||
```
|
||||
import (
|
||||
"flag"
|
||||
)
|
||||
```
|
||||
|
||||
[In part 1](../readme.md), we covered the fundamentals of writing basic Go <br/>
|
||||
[In part 2](../part-2.json/readme.md), we've learn how to use basic data structures like `json` so we can send\receive data. <br/>
|
||||
[Part 3](../part-3.http/readme.md) was about exposing data via a Web server.
|
||||
|
||||
We'll be combining these techniques so we can serve our `videos` data over a commandline application.
|
||||
|
||||
As always, let's start with our `dockerfile` , `main.go` and `videos.go` we created in Part 2
|
||||
|
||||
## Dev Environment
|
||||
|
||||
The same as Part 1+2+3, we start with a [dockerfile](./dockerfile) where we declare our version of `go`.
|
||||
|
||||
```
|
||||
cd golang\introduction\part-4.commandline
|
||||
|
||||
docker build --target dev . -t go
|
||||
docker run -it -v ${PWD}:/work go sh
|
||||
go version
|
||||
```
|
||||
|
||||
## Create our App
|
||||
|
||||
Create a new directory that holds defines our `repository` and holds our `module`
|
||||
|
||||
```
|
||||
mkdir videos
|
||||
cd videos
|
||||
```
|
||||
|
||||
* Define a module path
|
||||
|
||||
```
|
||||
# create a go module file
|
||||
|
||||
go mod init videos
|
||||
|
||||
```
|
||||
|
||||
## Create our base code
|
||||
|
||||
We start out all our applications with a `main.go` defining our `package`, declaring our `import` dependencies <br/>
|
||||
and our entrypoint `main()` function
|
||||
|
||||
```
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
fmt.Println("Hello, world.")
|
||||
}
|
||||
```
|
||||
|
||||
## Create our Videos app
|
||||
|
||||
Firstly, we create a seperate code file `videos.go` that deals with our YouTube videos <br/>
|
||||
|
||||
The `videos.go` file defines what a video `struct` looks like, a `getVideos()` function to retrieve <br/>
|
||||
videos list as a slice and a `saveVideos()` function to save videos to a file locally. <br/>
|
||||
|
||||
Let's copy the following content from Part 2 and create `videos.go` :
|
||||
|
||||
We want `videos.go` to be part of package main:
|
||||
|
||||
```
|
||||
package main
|
||||
|
||||
```
|
||||
|
||||
We import 2 packages, 1 for reading and writing files, and another for dealing with `json`
|
||||
|
||||
```
|
||||
import (
|
||||
"io/ioutil"
|
||||
"encoding/json"
|
||||
)
|
||||
|
||||
```
|
||||
|
||||
Then we define what a video `struct` looks like:
|
||||
|
||||
```
|
||||
|
||||
type video struct {
|
||||
Id string
|
||||
Title string
|
||||
Description string
|
||||
Imageurl string
|
||||
Url string
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
We have a function for retrieving `video` objects as a list of type `slice` :
|
||||
|
||||
```
|
||||
|
||||
func getVideos()(videos []video){
|
||||
|
||||
fileBytes, err := ioutil.ReadFile("./videos.json")
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
err = json.Unmarshal(fileBytes, &videos)
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return videos
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
We also need to copy our `videos.json` file which contains our video data. <br/>
|
||||
|
||||
And finally, we have a function that accepts a list of type `slice` and stores the videos to a local file
|
||||
|
||||
```
|
||||
func saveVideos(videos []video)(){
|
||||
|
||||
videoBytes, err := json.Marshal(videos)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
err = ioutil.WriteFile("./videos.json", videoBytes, 0644)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
## Flag Package
|
||||
|
||||
https://golang.org/pkg/flag/
|
||||
|
||||
Package flag implements command-line flag parsing.
|
||||
So we can run our videos app and pass it inputs like any other CLI.
|
||||
|
||||
Let's build a CLI tool that users our `getVideos()` and `saveVideos` functions.
|
||||
|
||||
To get all videos, perhaps we'd like a command
|
||||
```
|
||||
# get all videos
|
||||
videos get --all
|
||||
|
||||
# get video by ID
|
||||
videos get -id <video-id>
|
||||
|
||||
# add a video to our list
|
||||
videos add -id -title -url -imageurl -desc
|
||||
|
||||
|
||||
```
|
||||
To start, we import package `flag`
|
||||
|
||||
```
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
)
|
||||
```
|
||||
|
||||
|
||||
Let's define our subcommands in `main.go` :
|
||||
|
||||
```
|
||||
//'videos get' subcommand
|
||||
getCmd := flag.NewFlagSet("get", flag.ExitOnError)
|
||||
```
|
||||
|
||||
`videos get` command will need two inputs, `--all` if the user wants to return all videos, or `--id` if the user only wants a specific video
|
||||
|
||||
```
|
||||
// inputs for `videos get` command
|
||||
getAll := getCmd.Bool("all", false, "Get all videos")
|
||||
getID := getCmd.String("id", "", "YouTube video ID")
|
||||
```
|
||||
|
||||
`videos add` command will take a bit more inputs to be able to add a video to our storage.
|
||||
```
|
||||
addCmd := flag.NewFlagSet("add", flag.ExitOnError)
|
||||
|
||||
addID := addCmd.String("id", "", "YouTube video ID")
|
||||
addTitle := addCmd.String("title", "", "YouTube video Title")
|
||||
addUrl := addCmd.String("url", "", "YouTube video URL")
|
||||
addImageUrl := addCmd.String("imageurl", "", "YouTube video Image URL")
|
||||
addDesc := addCmd.String("desc", "", "YouTube video description")
|
||||
|
||||
|
||||
```
|
||||
|
||||
When a user runs our videos CLI tool, we may need to validate that
|
||||
our application receives the right subcommands. So lets ensure a simple validation to check if the user has passed a subcommand
|
||||
|
||||
To check the arguments passed to our CLI, we use the ["os"](https://golang.org/pkg/os/) package. Check the Args variable, it holds usefull information passed to our application including its name.
|
||||
`var Args []string`
|
||||
|
||||
We can do a simple check by ensuring the length of `os.Args` is atleast 2.
|
||||
|
||||
We firstly need to add `os` to our import section </br>
|
||||
Followed by our check:
|
||||
|
||||
```
|
||||
if len(os.Args) < 2 {
|
||||
fmt.Println("expected 'get' or 'add' subcommands")
|
||||
os.Exit(1)
|
||||
}
|
||||
```
|
||||
|
||||
## Handling our subcommands
|
||||
|
||||
So to handle each sub command like `get` and `add`, we add a simple
|
||||
`switch` statement that can branch into different pathways of execution,
|
||||
based on a variables content.
|
||||
|
||||
Let's take a look at this simple `switch` statement:
|
||||
|
||||
```
|
||||
//look at the 2nd argument's value
|
||||
switch os.Args[1] {
|
||||
case "get": // if its the 'get' command
|
||||
//hande get here
|
||||
case "add": // if its the 'add' command
|
||||
//hande add here
|
||||
default: // if we don't understand the input
|
||||
}
|
||||
```
|
||||
|
||||
Let's create seperate handler functions for each sub command to keep our code tidy:
|
||||
|
||||
```
|
||||
func HandleGet(getCmd *flag.FlagSet, all *bool, id *string){
|
||||
}
|
||||
|
||||
func HandleAdd(addCmd *flag.FlagSet,id *string, title *string, url *string, imageUrl *string, description *string ){
|
||||
}
|
||||
```
|
||||
|
||||
Now that we have seperate functions for each subcommand, we can take appropriate actions in each. Let's firstly parse the command flags for each subcommand:
|
||||
|
||||
This allows us to parse everything after the `videos <subcommand>` arguments:
|
||||
|
||||
```
|
||||
getCmd.Parse(os.Args[2:])
|
||||
```
|
||||
|
||||
## Input Validation
|
||||
|
||||
For our `HandleGet` function, let's validate input to ensure its correct.
|
||||
|
||||
```
|
||||
if *all == false && *id == "" {
|
||||
fmt.Print("id is required or specify --all for all videos")
|
||||
getCmd.PrintDefaults()
|
||||
os.Exit(1)
|
||||
}
|
||||
```
|
||||
|
||||
Let's handle the scenario if user passing `--all` flag:
|
||||
|
||||
```
|
||||
if *all {
|
||||
//return all videos
|
||||
videos := getVideos()
|
||||
|
||||
fmt.Printf("ID \t Title \t URL \t ImageURL \t Description \n")
|
||||
for _, video := range videos {
|
||||
fmt.Printf("%v \t %v \t %v \t %v \t %v \n",video.Id, video.Title, video.Url, video.Imageurl,video.Description)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
```
|
||||
|
||||
Let's handle when user is searching for a video by ID
|
||||
|
||||
```
|
||||
if *id != "" {
|
||||
videos := getVideos()
|
||||
id := *id
|
||||
for _, video := range videos {
|
||||
if id == video.Id {
|
||||
fmt.Printf("ID \t Title \t URL \t ImageURL \t Description \n")
|
||||
fmt.Printf("%v \t %v \t %v \t %v \t %v \n",video.Id, video.Title, video.Url, video.Imageurl,video.Description)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Parsing multiple fields
|
||||
|
||||
For our `HandleAdd` function, we need to validate multiple inputs, create a `video` struct, append it to the existing video list and save it back to file
|
||||
|
||||
Let's create a `ValidateVideo()` function with similar inputs to our `HandleAdd()`:
|
||||
|
||||
```
|
||||
func ValidateVideo(addCmd *flag.FlagSet,id *string, title *string, url *string, imageUrl *string, description *string ){
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Let's simply validate all fields since they are all required:
|
||||
|
||||
```
|
||||
if *id == "" || *title == "" || *url == "" || *imageUrl == "" || *description == "" {
|
||||
fmt.Print("all fields are required for adding a video")
|
||||
addCmd.PrintDefaults()
|
||||
os.Exit(1)
|
||||
}
|
||||
```
|
||||
|
||||
And we can now call this function in our add function:
|
||||
|
||||
```
|
||||
ValidateVideo(addCmd, id,title,url, imageUrl, description)
|
||||
```
|
||||
|
||||
## Adding our video
|
||||
|
||||
Now that we have some basic validation, not perfect, but good enough to get started, let's add our video to the existing file.
|
||||
|
||||
Define a video struct with the CLI input:
|
||||
|
||||
```
|
||||
video := video{
|
||||
Id: *id,
|
||||
Title: *title,
|
||||
Description: *description,
|
||||
Imageurl: *imageUrl,
|
||||
Url: *url,
|
||||
}
|
||||
```
|
||||
|
||||
Get the existing videos:
|
||||
|
||||
```
|
||||
videos := getVideos()
|
||||
```
|
||||
|
||||
Append our video to the list:
|
||||
|
||||
```
|
||||
videos = append(videos,video)
|
||||
```
|
||||
|
||||
Save the new updated video list:
|
||||
|
||||
```
|
||||
saveVideos(videos)
|
||||
```
|
||||
|
||||
# Build our Docker container
|
||||
|
||||
Let's uncomment all the build lines in the `dockerfile`
|
||||
Full `dockerfile` :
|
||||
|
||||
```
|
||||
FROM golang:1.15-alpine as dev
|
||||
|
||||
WORKDIR /work
|
||||
|
||||
FROM golang:1.15-alpine as build
|
||||
|
||||
WORKDIR /videos
|
||||
COPY ./videos/* /videos/
|
||||
RUN go build -o videos
|
||||
|
||||
|
||||
FROM alpine as runtime
|
||||
COPY --from=build /videos/videos /usr/local/bin/videos
|
||||
COPY ./videos/videos.json /
|
||||
COPY run.sh /
|
||||
RUN chmod +x /run.sh
|
||||
ENTRYPOINT [ "./run.sh" ]
|
||||
```
|
||||
|
||||
For our entrypoint, we need to create a shell script to accept all the arguments:
|
||||
|
||||
Let's create a script called `run.sh`
|
||||
|
||||
```
|
||||
#!/bin/sh
|
||||
|
||||
videos $@
|
||||
|
||||
```
|
||||
|
||||
Build :
|
||||
```
|
||||
cd golang\introduction\part-4.commandline
|
||||
docker build . -t videos
|
||||
```
|
||||
|
||||
Run :
|
||||
```
|
||||
docker run -it videos get --help
|
||||
```
|
3
golang/introduction/part-4.commandline/run.sh
Normal file
3
golang/introduction/part-4.commandline/run.sh
Normal file
@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
videos $@
|
3
golang/introduction/part-4.commandline/videos/go.mod
Normal file
3
golang/introduction/part-4.commandline/videos/go.mod
Normal file
@ -0,0 +1,3 @@
|
||||
module videos
|
||||
|
||||
go 1.15
|
111
golang/introduction/part-4.commandline/videos/main.go
Normal file
111
golang/introduction/part-4.commandline/videos/main.go
Normal file
@ -0,0 +1,111 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
||||
//'videos get' subcommand
|
||||
getCmd := flag.NewFlagSet("get", flag.ExitOnError)
|
||||
|
||||
// inputs for `videos get` command
|
||||
getAll := getCmd.Bool("all", false, "Get all videos")
|
||||
getID := getCmd.String("id", "", "YouTube video ID")
|
||||
|
||||
//'videos add' subcommand
|
||||
addCmd := flag.NewFlagSet("add", flag.ExitOnError)
|
||||
|
||||
// inputs for `videos add` command
|
||||
addID := addCmd.String("id", "", "YouTube video ID")
|
||||
addTitle := addCmd.String("title", "", "YouTube video Title")
|
||||
addUrl := addCmd.String("url", "", "YouTube video URL")
|
||||
addImageUrl := addCmd.String("imageurl", "", "YouTube video Image URL")
|
||||
addDesc := addCmd.String("desc", "", "YouTube video description")
|
||||
|
||||
if len(os.Args) < 2 {
|
||||
fmt.Println("expected 'get' or 'add' subcommands")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
//look at the 2nd argument's value
|
||||
switch os.Args[1] {
|
||||
case "get": // if its the 'get' command
|
||||
HandleGet(getCmd, getAll, getID)
|
||||
case "add": // if its the 'add' command
|
||||
HandleAdd(addCmd, addID,addTitle,addUrl, addImageUrl, addDesc)
|
||||
default: // if we don't understand the input
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
func HandleGet(getCmd *flag.FlagSet, all *bool, id *string){
|
||||
|
||||
getCmd.Parse(os.Args[2:])
|
||||
|
||||
if *all == false && *id == "" {
|
||||
fmt.Print("id is required or specify --all for all videos")
|
||||
getCmd.PrintDefaults()
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if *all {
|
||||
//return all videos
|
||||
videos := getVideos()
|
||||
|
||||
fmt.Printf("ID \t Title \t URL \t ImageURL \t Description \n")
|
||||
for _, video := range videos {
|
||||
fmt.Printf("%v \t %v \t %v \t %v \t %v \n",video.Id, video.Title, video.Url, video.Imageurl,video.Description)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if *id != "" {
|
||||
videos := getVideos()
|
||||
id := *id
|
||||
for _, video := range videos {
|
||||
if id == video.Id {
|
||||
fmt.Printf("ID \t Title \t URL \t ImageURL \t Description \n")
|
||||
fmt.Printf("%v \t %v \t %v \t %v \t %v \n",video.Id, video.Title, video.Url, video.Imageurl,video.Description)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
func ValidateVideo(addCmd *flag.FlagSet,id *string, title *string, url *string, imageUrl *string, description *string ){
|
||||
|
||||
addCmd.Parse(os.Args[2:])
|
||||
|
||||
if *id == "" || *title == "" || *url == "" || *imageUrl == "" || *description == "" {
|
||||
fmt.Print("all fields are required for adding a video")
|
||||
addCmd.PrintDefaults()
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func HandleAdd(addCmd *flag.FlagSet,id *string, title *string, url *string, imageUrl *string, description *string ){
|
||||
|
||||
ValidateVideo(addCmd, id,title,url, imageUrl, description)
|
||||
|
||||
video := video{
|
||||
Id: *id,
|
||||
Title: *title,
|
||||
Description: *description,
|
||||
Imageurl: *imageUrl,
|
||||
Url: *url,
|
||||
}
|
||||
|
||||
videos := getVideos()
|
||||
videos = append(videos,video)
|
||||
|
||||
saveVideos(videos)
|
||||
|
||||
}
|
BIN
golang/introduction/part-4.commandline/videos/videos
Normal file
BIN
golang/introduction/part-4.commandline/videos/videos
Normal file
Binary file not shown.
45
golang/introduction/part-4.commandline/videos/videos.go
Normal file
45
golang/introduction/part-4.commandline/videos/videos.go
Normal file
@ -0,0 +1,45 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"encoding/json"
|
||||
)
|
||||
|
||||
type video struct {
|
||||
Id string
|
||||
Title string
|
||||
Description string
|
||||
Imageurl string
|
||||
Url string
|
||||
}
|
||||
|
||||
func getVideos()(videos []video){
|
||||
|
||||
fileBytes, err := ioutil.ReadFile("./videos.json")
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
err = json.Unmarshal(fileBytes, &videos)
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return videos
|
||||
}
|
||||
|
||||
func saveVideos(videos []video)(){
|
||||
|
||||
videoBytes, err := json.Marshal(videos)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
err = ioutil.WriteFile("./videos.json", videoBytes, 0644)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
}
|
16
golang/introduction/part-4.commandline/videos/videos.json
Normal file
16
golang/introduction/part-4.commandline/videos/videos.json
Normal file
@ -0,0 +1,16 @@
|
||||
[
|
||||
{
|
||||
"Id": "QThadS3Soig",
|
||||
"Title": "Kubernetes on Amazon",
|
||||
"Description": "",
|
||||
"Imageurl": "https://i.ytimg.com/vi/QThadS3Soig/sddefault.jpg",
|
||||
"Url": "https://youtu.be/QThadS3Soig"
|
||||
},
|
||||
{
|
||||
"Id": "eyvLwK5C2dw",
|
||||
"Title": "Kubernetes on Azure",
|
||||
"Description": "",
|
||||
"Imageurl": "https://i.ytimg.com/vi/eyvLwK5C2dw/mqdefault.jpg?sqp=CISC_PoF\u0026rs=AOn4CLDo7kizrJozB0pxBhxL9JbyiW_EPw",
|
||||
"Url": "https://youtu.be/eyvLwK5C2dw"
|
||||
}
|
||||
]
|
@ -22,6 +22,7 @@ spec:
|
||||
cp /tmp/redis/redis.conf /etc/redis/redis.conf
|
||||
|
||||
echo "finding master..."
|
||||
MASTER_FDQN=`hostname -f | sed -e 's/redis-[0-9]\./redis-0./'`
|
||||
if [ "$(redis-cli -h sentinel -p 5000 ping)" != "PONG" ]; then
|
||||
echo "master not found, defaulting to redis-0"
|
||||
|
||||
@ -29,7 +30,7 @@ spec:
|
||||
echo "this is redis-0, not updating config..."
|
||||
else
|
||||
echo "updating redis.conf..."
|
||||
echo "slaveof redis-0.redis.redis.svc.cluster.local 6379" >> /etc/redis/redis.conf
|
||||
echo "slaveof $MASTER_FDQN 6379" >> /etc/redis/redis.conf
|
||||
fi
|
||||
else
|
||||
echo "sentinel found, finding master"
|
||||
@ -82,4 +83,4 @@ spec:
|
||||
targetPort: 6379
|
||||
name: redis
|
||||
selector:
|
||||
app: redis
|
||||
app: redis
|
||||
|
144
tracing/README.md
Normal file
144
tracing/README.md
Normal file
@ -0,0 +1,144 @@
|
||||
# Introduction to Distributed Tracing
|
||||
|
||||
In this episode we take a look at distributed tracing.
|
||||
We'll take a look at the concept, what distributed tracing is, what problems it solves, how to emit traces and the platform architecture to collect traces.
|
||||
|
||||
## Example microservice architecture
|
||||
|
||||
First of all, we need an example application.
|
||||
In this demo, I have a few microservices that work together to form a video catalog.
|
||||
|
||||
## A simple Web UI: videos-web
|
||||
<hr/>
|
||||
<br/>
|
||||
|
||||
Consider `videos-web` <br/>
|
||||
It's an HTML application that lists a bunch of playlists with videos in them.
|
||||
|
||||
```
|
||||
+------------+
|
||||
| videos-web |
|
||||
| |
|
||||
+------------+
|
||||
```
|
||||
<br/>
|
||||
|
||||
## A simple API: playlists-api
|
||||
<hr/>
|
||||
<br/>
|
||||
|
||||
For `videos-web` to get any content, it needs to make a call to `playlists-api`
|
||||
|
||||
```
|
||||
+------------+ +---------------+
|
||||
| videos-web +---->+ playlists-api |
|
||||
| | | |
|
||||
+------------+ +---------------+
|
||||
|
||||
```
|
||||
|
||||
Playlists consist of data like `title`, `description` etc, and a list of `videos`. <br/>
|
||||
Playlists are stored in a database. <br/>
|
||||
`playlists-api` stores its data in a database
|
||||
|
||||
```
|
||||
+------------+ +---------------+ +--------------+
|
||||
| videos-web +---->+ playlists-api +--->+ playlists-db |
|
||||
| | | | | |
|
||||
+------------+ +---------------+ +--------------+
|
||||
|
||||
```
|
||||
|
||||
<br/>
|
||||
|
||||
## A little complexity
|
||||
<hr/>
|
||||
<br/>
|
||||
|
||||
Each playlist item contains only a list of video id's. <br/>
|
||||
A playlist does not have the full metadata of each video. <br/>
|
||||
|
||||
Example `playlist`:
|
||||
```
|
||||
{
|
||||
"id" : "playlist-01",
|
||||
"title": "Cool playlist",
|
||||
"videos" : [ "video-1", "video-x" , "video-b"]
|
||||
}
|
||||
```
|
||||
Take not above `videos: []` is a list of video id's <br/>
|
||||
|
||||
Videos have their own `title` and `description` and other metadata. <br/>
|
||||
|
||||
To get this data, we need a `videos-api` <br/>
|
||||
This `videos-api` has its own database too <br/>
|
||||
|
||||
```
|
||||
+------------+ +-----------+
|
||||
| videos-api +------>+ videos-db |
|
||||
| | | |
|
||||
+------------+ +-----------+
|
||||
```
|
||||
|
||||
For the `playlists-api` to load all the video data, it needs to call `videos-api` for each video ID it has.<br/>
|
||||
<br/>
|
||||
|
||||
## Traffic flow
|
||||
<hr/>
|
||||
<br/>
|
||||
A single `GET` request to the `playlists-api` will get all the playlists
|
||||
from its database with a single DB call <br/>
|
||||
|
||||
For every playlist and every video in each list, a separate `GET` call will be made to the `videos-api` which will
|
||||
retrieve the video metadata from its database. <br/>
|
||||
|
||||
This will result in many network fanouts between `playlists-api` and `videos-api` and many call to its database. <br/>
|
||||
This is intentional to demonstrate a busy network.
|
||||
|
||||
<br/>
|
||||
|
||||
## Full application architecture
|
||||
<hr/>
|
||||
<br/>
|
||||
|
||||
```
|
||||
|
||||
+------------+ +---------------+ +--------------+
|
||||
| videos-web +---->+ playlists-api +--->+ playlists-db |
|
||||
| | | | | |
|
||||
+------------+ +-----+---------+ +--------------+
|
||||
|
|
||||
v
|
||||
+-----+------+ +-----------+
|
||||
| videos-api +------>+ videos-db |
|
||||
| | | |
|
||||
+------------+ +-----------+
|
||||
|
||||
```
|
||||
<br/>
|
||||
|
||||
## Run the apps: Docker
|
||||
<hr/>
|
||||
<br/>
|
||||
There is a `docker-compose.yaml` in this directory. <br/>
|
||||
Change your terminal to this folder and run:
|
||||
|
||||
```
|
||||
cd tracing
|
||||
|
||||
docker-compose build
|
||||
|
||||
docker-compose up
|
||||
|
||||
```
|
||||
|
||||
You can access the app on `http://localhost`. <br/>
|
||||
You should now see the complete architecture in the browser
|
||||
<br/>
|
||||
|
||||
## Traces
|
||||
|
||||
<hr/>
|
||||
<br/>
|
||||
|
||||
To see our traces, we can access the Jaeger UI on `http://localhost:16686`
|
192
tracing/applications-go/playlists-api/app.go
Normal file
192
tracing/applications-go/playlists-api/app.go
Normal file
@ -0,0 +1,192 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"github.com/julienschmidt/httprouter"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"context"
|
||||
"github.com/go-redis/redis/v8"
|
||||
|
||||
"github.com/opentracing/opentracing-go"
|
||||
"github.com/uber/jaeger-client-go"
|
||||
"github.com/uber/jaeger-client-go/config"
|
||||
"github.com/opentracing/opentracing-go/ext"
|
||||
)
|
||||
|
||||
const serviceName = "playlists-api"
|
||||
|
||||
var environment = os.Getenv("ENVIRONMENT")
|
||||
var redis_host = os.Getenv("REDIS_HOST")
|
||||
var redis_port = os.Getenv("REDIS_PORT")
|
||||
var ctx = context.Background()
|
||||
var rdb *redis.Client
|
||||
|
||||
func main() {
|
||||
|
||||
cfg := &config.Configuration{
|
||||
ServiceName: serviceName,
|
||||
|
||||
// "const" sampler is a binary sampling strategy: 0=never sample, 1=always sample.
|
||||
Sampler: &config.SamplerConfig{
|
||||
Type: "const",
|
||||
Param: 1,
|
||||
},
|
||||
|
||||
// Log the emitted spans to stdout.
|
||||
Reporter: &config.ReporterConfig{
|
||||
LogSpans: true,
|
||||
LocalAgentHostPort: "jaeger:6831",
|
||||
},
|
||||
}
|
||||
|
||||
tracer, closer, err := cfg.NewTracer(config.Logger(jaeger.StdLogger))
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("ERROR: cannot init Jaeger: %v\n", err))
|
||||
}
|
||||
defer closer.Close()
|
||||
opentracing.SetGlobalTracer(tracer)
|
||||
|
||||
router := httprouter.New()
|
||||
|
||||
router.GET("/", func(w http.ResponseWriter, r *http.Request, p httprouter.Params){
|
||||
|
||||
spanCtx, _ := tracer.Extract(
|
||||
opentracing.HTTPHeaders,
|
||||
opentracing.HTTPHeadersCarrier(r.Header),
|
||||
)
|
||||
|
||||
span := tracer.StartSpan("/ GET", ext.RPCServerOption(spanCtx))
|
||||
defer span.Finish()
|
||||
|
||||
cors(w)
|
||||
|
||||
ctx := opentracing.ContextWithSpan(context.Background(), span)
|
||||
playlistsJson := getPlaylists(ctx)
|
||||
|
||||
playlists := []playlist{}
|
||||
err := json.Unmarshal([]byte(playlistsJson), &playlists)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
//get videos for each playlist from videos api
|
||||
for pi := range playlists {
|
||||
|
||||
vs := []videos{}
|
||||
for vi := range playlists[pi].Videos {
|
||||
|
||||
span, _ := opentracing.StartSpanFromContext(ctx, "videos-api GET")
|
||||
|
||||
v := videos{}
|
||||
|
||||
req, err := http.NewRequest("GET", "http://videos-api:10010/" + playlists[pi].Videos[vi].Id, nil)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
span.Tracer().Inject(
|
||||
span.Context(),
|
||||
opentracing.HTTPHeaders,
|
||||
opentracing.HTTPHeadersCarrier(req.Header),
|
||||
)
|
||||
|
||||
videoResp, err :=http.DefaultClient.Do(req)
|
||||
|
||||
span.Finish()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
span.SetTag("error", true)
|
||||
break
|
||||
}
|
||||
|
||||
defer videoResp.Body.Close()
|
||||
video, err := ioutil.ReadAll(videoResp.Body)
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
|
||||
err = json.Unmarshal(video, &v)
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
vs = append(vs, v)
|
||||
|
||||
}
|
||||
|
||||
playlists[pi].Videos = vs
|
||||
}
|
||||
|
||||
playlistsBytes, err := json.Marshal(playlists)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
reader := bytes.NewReader(playlistsBytes)
|
||||
if b, err := ioutil.ReadAll(reader); err == nil {
|
||||
fmt.Fprintf(w, "%s", string(b))
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
r := redis.NewClient(&redis.Options{
|
||||
Addr: redis_host + ":" + redis_port,
|
||||
DB: 0,
|
||||
})
|
||||
rdb = r
|
||||
|
||||
fmt.Println("Running...")
|
||||
log.Fatal(http.ListenAndServe(":10010", router))
|
||||
}
|
||||
|
||||
func getPlaylists(ctx context.Context)(response string){
|
||||
|
||||
span, _ := opentracing.StartSpanFromContext(ctx, "redis-get")
|
||||
defer span.Finish()
|
||||
playlistData, err := rdb.Get(ctx, "playlists").Result()
|
||||
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
fmt.Println("error occured retrieving playlists from Redis")
|
||||
span.SetTag("error", true)
|
||||
return "[]"
|
||||
}
|
||||
|
||||
return playlistData
|
||||
}
|
||||
|
||||
type playlist struct {
|
||||
Id string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Videos []videos `json:"videos"`
|
||||
}
|
||||
|
||||
type videos struct {
|
||||
Id string `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description"`
|
||||
Imageurl string `json:"imageurl"`
|
||||
Url string `json:"url"`
|
||||
|
||||
}
|
||||
|
||||
type stop struct {
|
||||
error
|
||||
}
|
||||
|
||||
func cors(writer http.ResponseWriter) () {
|
||||
if(environment == "DEBUG"){
|
||||
writer.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
|
||||
writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With, X-MY-API-Version")
|
||||
writer.Header().Set("Access-Control-Allow-Credentials", "true")
|
||||
writer.Header().Set("Access-Control-Allow-Origin", "*")
|
||||
}
|
||||
}
|
70
tracing/applications-go/playlists-api/deploy.yaml
Normal file
70
tracing/applications-go/playlists-api/deploy.yaml
Normal file
@ -0,0 +1,70 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: playlists-api
|
||||
labels:
|
||||
app: playlists-api
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: playlists-api
|
||||
replicas: 1
|
||||
strategy:
|
||||
type: RollingUpdate
|
||||
rollingUpdate:
|
||||
maxSurge: 1
|
||||
maxUnavailable: 0
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: playlists-api
|
||||
spec:
|
||||
containers:
|
||||
- name: playlists-api
|
||||
image: aimvector/jaeger-tracing:playlists-api-1.0.0
|
||||
imagePullPolicy : Always
|
||||
ports:
|
||||
- containerPort: 10010
|
||||
env:
|
||||
- name: "ENVIRONMENT"
|
||||
value: "DEBUG"
|
||||
- name: "REDIS_HOST"
|
||||
value: "playlists-db"
|
||||
- name: "REDIS_PORT"
|
||||
value: "6379"
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: playlists-api
|
||||
labels:
|
||||
app: playlists-api
|
||||
spec:
|
||||
type: ClusterIP
|
||||
selector:
|
||||
app: playlists-api
|
||||
ports:
|
||||
- protocol: TCP
|
||||
name: http
|
||||
port: 80
|
||||
targetPort: 10010
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1beta1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
annotations:
|
||||
kubernetes.io/ingress.class: "nginx"
|
||||
nginx.ingress.kubernetes.io/ssl-redirect: "false"
|
||||
nginx.ingress.kubernetes.io/rewrite-target: /$2
|
||||
name: playlists-api
|
||||
spec:
|
||||
rules:
|
||||
- host: servicemesh.demo
|
||||
http:
|
||||
paths:
|
||||
- path: /api/playlists(/|$)(.*)
|
||||
backend:
|
||||
serviceName: playlists-api
|
||||
servicePort: 80
|
||||
|
||||
|
18
tracing/applications-go/playlists-api/dockerfile
Normal file
18
tracing/applications-go/playlists-api/dockerfile
Normal file
@ -0,0 +1,18 @@
|
||||
FROM golang:1.15-alpine as build
|
||||
RUN apk add --no-cache git
|
||||
|
||||
WORKDIR /src
|
||||
|
||||
COPY go.sum /src/
|
||||
COPY go.mod /src/
|
||||
RUN go mod download
|
||||
|
||||
COPY app.go /src
|
||||
|
||||
RUN go build -o app
|
||||
|
||||
FROM alpine:3.12
|
||||
|
||||
RUN mkdir -p /app
|
||||
COPY --from=build /src/app /app/app
|
||||
CMD ["./app/app"]
|
14
tracing/applications-go/playlists-api/go.mod
Normal file
14
tracing/applications-go/playlists-api/go.mod
Normal file
@ -0,0 +1,14 @@
|
||||
module example.com/playlists-api
|
||||
|
||||
go 1.14
|
||||
|
||||
require (
|
||||
github.com/go-redis/redis/v8 v8.0.0-beta.7
|
||||
github.com/julienschmidt/httprouter v1.3.0
|
||||
github.com/opentracing/opentracing-go v1.1.1-0.20190913142402-a7454ce5950e
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/sirupsen/logrus v1.6.0
|
||||
github.com/uber/jaeger-client-go v2.25.0+incompatible
|
||||
github.com/uber/jaeger-lib v2.4.0+incompatible // indirect
|
||||
go.uber.org/atomic v1.7.0 // indirect
|
||||
)
|
142
tracing/applications-go/playlists-api/go.sum
Normal file
142
tracing/applications-go/playlists-api/go.sum
Normal file
@ -0,0 +1,142 @@
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/DataDog/sketches-go v0.0.0-20190923095040-43f19ad77ff7/go.mod h1:Q5DbzQ+3AkgGwymQO7aZFNP7ns2lZKGtvRBzRXfdi60=
|
||||
github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
|
||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200624174652-8d2f3be8b2d9 h1:h2Ul3Ym2iVZWMQGYmulVUJ4LSkBm1erp9mUkPwtMoLg=
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200624174652-8d2f3be8b2d9/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-redis/redis v6.15.8+incompatible h1:BKZuG6mCnRj5AOaWJXoCgf6rqTYnYJLe4en2hxT7r9o=
|
||||
github.com/go-redis/redis/v8 v8.0.0-beta.7 h1:4HiY+qfsyz8OUr9zyAP2T1CJ0SFRY4mKFvm9TEznuv8=
|
||||
github.com/go-redis/redis/v8 v8.0.0-beta.7/go.mod h1:FGJAWDWFht1sQ4qxyJHZZbVyvnVcKQN0E3u5/5lRz+g=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U=
|
||||
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/opentracing/opentracing-go v1.1.1-0.20190913142402-a7454ce5950e h1:fI6mGTyggeIYVmGhf80XFHxTupjOexbCppgTNDkv9AA=
|
||||
github.com/opentracing/opentracing-go v1.1.1-0.20190913142402-a7454ce5950e/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I=
|
||||
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/uber/jaeger-client-go v1.6.0 h1:3+zLlq+4npI5fg8IsgAje3YsP7TcEdNzJScyqFIzxEQ=
|
||||
github.com/uber/jaeger-client-go v2.25.0+incompatible h1:IxcNZ7WRY1Y3G4poYlx24szfsn/3LvK9QHCq9oQw8+U=
|
||||
github.com/uber/jaeger-client-go v2.25.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
|
||||
github.com/uber/jaeger-lib v1.5.0 h1:OHbgr8l656Ub3Fw5k9SWnBfIEwvoHQ+W2y+Aa9D1Uyo=
|
||||
github.com/uber/jaeger-lib v2.4.0+incompatible h1:fY7QsGQWiCt8pajv4r7JEvmATdCVaWxXbjwyYwsNaLQ=
|
||||
github.com/uber/jaeger-lib v2.4.0+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
|
||||
go.opentelemetry.io/otel v0.7.0 h1:u43jukpwqR8EsyeJOMgrsUgZwVI1e1eVw7yuzRkD1l0=
|
||||
go.opentelemetry.io/otel v0.7.0/go.mod h1:aZMyHG5TqDOXEgH2tyLiXSUKly1jT3yqE9PmrzIeCdo=
|
||||
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
|
||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20200513190911-00229845015e h1:rMqLP+9XLy+LdbCXHjJHAmTfXCr93W7oruWA6Hq1Alc=
|
||||
golang.org/x/exp v0.0.0-20200513190911-00229845015e/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw=
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191010194322-b09406accb47 h1:/XfQ9z7ib8eEJX2hdgFTZJ/ntt0swNk5oYBziWeTCvY=
|
||||
golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20191009194640-548a555dbc03/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||
google.golang.org/grpc v1.30.0 h1:M5a8xTlYTxwMn5ZFkwhRabsygDY5G8TYLyQDBxJNAxE=
|
||||
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
36
tracing/applications-go/playlists-db/appendonly.aof
Normal file
36
tracing/applications-go/playlists-db/appendonly.aof
Normal file
@ -0,0 +1,36 @@
|
||||
*2
|
||||
$6
|
||||
SELECT
|
||||
$1
|
||||
0
|
||||
*3
|
||||
$3
|
||||
set
|
||||
$9
|
||||
playlists
|
||||
$515
|
||||
|
||||
[
|
||||
{
|
||||
"id" : "1",
|
||||
"name" : "CI/CD",
|
||||
"videos": [ { "id" : "OFgziggbCOg"}, { "id" : "myCcJJ_Fk10"}, { "id" : "2WSJF7d8dUg"}]
|
||||
},
|
||||
{
|
||||
"id" : "2",
|
||||
"name" : "K8s in the Cloud",
|
||||
"videos": [ { "id" : "QThadS3Soig"}, { "id" : "eyvLwK5C2dw"}]
|
||||
},
|
||||
{
|
||||
"id" : "3",
|
||||
"name" : "Storage and MessageBrokers",
|
||||
"videos": [ { "id" : "JmCn7k0PlV4"}, { "id" : "_lpDfMkxccc"}]
|
||||
|
||||
},
|
||||
{
|
||||
"id" : "4",
|
||||
"name" : "K8s Autoscaling",
|
||||
"videos": [ { "id" : "jM36M39MA3I"}, { "id" : "FfDI08sgrYY"}]
|
||||
}
|
||||
]
|
||||
|
BIN
tracing/applications-go/playlists-db/configmap.yaml
Normal file
BIN
tracing/applications-go/playlists-db/configmap.yaml
Normal file
Binary file not shown.
59
tracing/applications-go/playlists-db/deploy.yaml
Normal file
59
tracing/applications-go/playlists-db/deploy.yaml
Normal file
@ -0,0 +1,59 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: playlists-db
|
||||
labels:
|
||||
app: playlists-db
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: playlists-db
|
||||
replicas: 1
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: playlists-db
|
||||
spec:
|
||||
initContainers:
|
||||
- name: data
|
||||
image: busybox
|
||||
command: [ "sh", "-c" ]
|
||||
args:
|
||||
- |
|
||||
cp /config/appendonly.aof /tmp/appendonly.aof
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /tmp/
|
||||
- name: config
|
||||
mountPath: /config/
|
||||
containers:
|
||||
- name: playlists-db
|
||||
image: redis:6.0-alpine
|
||||
ports:
|
||||
- containerPort: 6379
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /tmp/
|
||||
command: [ "redis-server"]
|
||||
args: ["--dir", "/tmp", "--appendonly", "yes"]
|
||||
volumes:
|
||||
- name: data
|
||||
emptyDir: {}
|
||||
- name: config
|
||||
configMap:
|
||||
name: playlists-db
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: playlists-db
|
||||
labels:
|
||||
app: playlists-db
|
||||
spec:
|
||||
type: ClusterIP
|
||||
selector:
|
||||
app: playlists-db
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 6379
|
||||
targetPort: 6379
|
151
tracing/applications-go/videos-api/app.go
Normal file
151
tracing/applications-go/videos-api/app.go
Normal file
@ -0,0 +1,151 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"github.com/julienschmidt/httprouter"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/go-redis/redis/v8"
|
||||
"fmt"
|
||||
"context"
|
||||
"time"
|
||||
"strings"
|
||||
"os"
|
||||
"math/rand"
|
||||
"github.com/opentracing/opentracing-go"
|
||||
"github.com/uber/jaeger-client-go"
|
||||
"github.com/uber/jaeger-client-go/config"
|
||||
"github.com/opentracing/opentracing-go/ext"
|
||||
)
|
||||
|
||||
//TODO : https://opentracing.io/guides/golang/quick-start/
|
||||
// docker run --rm -it -p 6831:6831/udp -p 16686:16686 -p 14269:14269 --net tracing --name jaeger jaegertracing/all-in-one:latest
|
||||
|
||||
const serviceName = "videos-api"
|
||||
|
||||
var environment = os.Getenv("ENVIRONMENT")
|
||||
var redis_host = os.Getenv("REDIS_HOST")
|
||||
var redis_port = os.Getenv("REDIS_PORT")
|
||||
var flaky = os.Getenv("FLAKY")
|
||||
var delay = os.Getenv("DELAY")
|
||||
|
||||
var ctx = context.Background()
|
||||
var rdb *redis.Client
|
||||
|
||||
func main() {
|
||||
|
||||
cfg := &config.Configuration{
|
||||
ServiceName: serviceName,
|
||||
|
||||
// "const" sampler is a binary sampling strategy: 0=never sample, 1=always sample.
|
||||
Sampler: &config.SamplerConfig{
|
||||
Type: "const",
|
||||
Param: 1,
|
||||
},
|
||||
|
||||
// Log the emitted spans to stdout.
|
||||
Reporter: &config.ReporterConfig{
|
||||
LogSpans: true,
|
||||
LocalAgentHostPort: "jaeger:6831",
|
||||
},
|
||||
}
|
||||
|
||||
tracer, closer, err := cfg.NewTracer(config.Logger(jaeger.StdLogger))
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("ERROR: cannot init Jaeger: %v\n", err))
|
||||
}
|
||||
defer closer.Close()
|
||||
opentracing.SetGlobalTracer(tracer)
|
||||
|
||||
router := httprouter.New()
|
||||
|
||||
router.GET("/:id", func(w http.ResponseWriter, r *http.Request, p httprouter.Params){
|
||||
|
||||
spanCtx, _ := tracer.Extract(
|
||||
opentracing.HTTPHeaders,
|
||||
opentracing.HTTPHeadersCarrier(r.Header),
|
||||
)
|
||||
|
||||
span := tracer.StartSpan("/id GET", ext.RPCServerOption(spanCtx))
|
||||
defer span.Finish()
|
||||
|
||||
if flaky == "true" {
|
||||
if rand.Intn(90) < 30 {
|
||||
panic("flaky error occurred ")
|
||||
}
|
||||
}
|
||||
|
||||
ctx := opentracing.ContextWithSpan(context.Background(), span)
|
||||
video := video(w,r,p, ctx)
|
||||
|
||||
if strings.Contains(video, "jM36M39MA3I") && delay == "true" {
|
||||
time.Sleep(6 * time.Second)
|
||||
}
|
||||
|
||||
cors(w)
|
||||
fmt.Fprintf(w, "%s", video)
|
||||
|
||||
})
|
||||
|
||||
r := redis.NewClient(&redis.Options{
|
||||
Addr: redis_host + ":" + redis_port,
|
||||
DB: 0,
|
||||
})
|
||||
rdb = r
|
||||
|
||||
fmt.Println("Running...")
|
||||
log.Fatal(http.ListenAndServe(":10010", router))
|
||||
}
|
||||
|
||||
func video(writer http.ResponseWriter, request *http.Request, p httprouter.Params, ctx context.Context)(response string){
|
||||
|
||||
span, _ := opentracing.StartSpanFromContext(ctx, "redis-get")
|
||||
defer span.Finish()
|
||||
id := p.ByName("id")
|
||||
|
||||
videoData, err := rdb.Get(ctx, id).Result()
|
||||
if err == redis.Nil {
|
||||
|
||||
span.Tracer().Inject(
|
||||
span.Context(),
|
||||
opentracing.HTTPHeaders,
|
||||
opentracing.HTTPHeadersCarrier(request.Header),
|
||||
)
|
||||
|
||||
return "{}"
|
||||
|
||||
|
||||
} else if err != nil {
|
||||
panic(err)
|
||||
} else {
|
||||
|
||||
span.Tracer().Inject(
|
||||
span.Context(),
|
||||
opentracing.HTTPHeaders,
|
||||
opentracing.HTTPHeadersCarrier(request.Header),
|
||||
)
|
||||
|
||||
return videoData
|
||||
}
|
||||
}
|
||||
|
||||
type stop struct {
|
||||
error
|
||||
}
|
||||
|
||||
func cors(writer http.ResponseWriter) () {
|
||||
if(environment == "DEBUG"){
|
||||
writer.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
|
||||
writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With, X-MY-API-Version")
|
||||
writer.Header().Set("Access-Control-Allow-Credentials", "true")
|
||||
writer.Header().Set("Access-Control-Allow-Origin", "*")
|
||||
}
|
||||
}
|
||||
|
||||
type videos struct {
|
||||
Id string `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description"`
|
||||
Imageurl string `json:"imageurl"`
|
||||
Url string `json:"url"`
|
||||
|
||||
}
|
55
tracing/applications-go/videos-api/deploy.yaml
Normal file
55
tracing/applications-go/videos-api/deploy.yaml
Normal file
@ -0,0 +1,55 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: videos-api
|
||||
labels:
|
||||
app: videos-api
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: videos-api
|
||||
replicas: 1
|
||||
strategy:
|
||||
type: RollingUpdate
|
||||
rollingUpdate:
|
||||
maxSurge: 1
|
||||
maxUnavailable: 0
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: videos-api
|
||||
spec:
|
||||
containers:
|
||||
- name: videos-api
|
||||
image: aimvector/jaeger-tracing:videos-api-1.0.0
|
||||
imagePullPolicy : Always
|
||||
ports:
|
||||
- containerPort: 10010
|
||||
env:
|
||||
- name: "ENVIRONMENT"
|
||||
value: "DEBUG"
|
||||
- name: "REDIS_HOST"
|
||||
value: "videos-db"
|
||||
- name: "REDIS_PORT"
|
||||
value: "6379"
|
||||
- name: "FLAKY"
|
||||
value: "false"
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: videos-api
|
||||
labels:
|
||||
app: videos-api
|
||||
spec:
|
||||
type: ClusterIP
|
||||
selector:
|
||||
app: videos-api
|
||||
ports:
|
||||
- protocol: TCP
|
||||
name: http
|
||||
port: 10010
|
||||
targetPort: 10010
|
||||
---
|
||||
|
||||
|
18
tracing/applications-go/videos-api/dockerfile
Normal file
18
tracing/applications-go/videos-api/dockerfile
Normal file
@ -0,0 +1,18 @@
|
||||
FROM golang:1.15-alpine as build
|
||||
RUN apk add --no-cache git
|
||||
|
||||
WORKDIR /src
|
||||
|
||||
COPY go.sum /src/
|
||||
COPY go.mod /src/
|
||||
RUN go mod download
|
||||
|
||||
COPY app.go /src
|
||||
|
||||
RUN go build -o app
|
||||
|
||||
FROM alpine:3.12
|
||||
|
||||
RUN mkdir -p /app
|
||||
COPY --from=build /src/app /app/app
|
||||
CMD ["./app/app"]
|
14
tracing/applications-go/videos-api/go.mod
Normal file
14
tracing/applications-go/videos-api/go.mod
Normal file
@ -0,0 +1,14 @@
|
||||
module example.com/playlists-api
|
||||
|
||||
go 1.14
|
||||
|
||||
require (
|
||||
github.com/go-redis/redis/v8 v8.0.0-beta.7
|
||||
github.com/julienschmidt/httprouter v1.3.0
|
||||
github.com/opentracing/opentracing-go v1.1.1-0.20190913142402-a7454ce5950e
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/sirupsen/logrus v1.6.0
|
||||
github.com/uber/jaeger-client-go v2.25.0+incompatible
|
||||
github.com/uber/jaeger-lib v2.4.0+incompatible // indirect
|
||||
go.uber.org/atomic v1.7.0 // indirect
|
||||
)
|
142
tracing/applications-go/videos-api/go.sum
Normal file
142
tracing/applications-go/videos-api/go.sum
Normal file
@ -0,0 +1,142 @@
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/DataDog/sketches-go v0.0.0-20190923095040-43f19ad77ff7/go.mod h1:Q5DbzQ+3AkgGwymQO7aZFNP7ns2lZKGtvRBzRXfdi60=
|
||||
github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
|
||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200624174652-8d2f3be8b2d9 h1:h2Ul3Ym2iVZWMQGYmulVUJ4LSkBm1erp9mUkPwtMoLg=
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200624174652-8d2f3be8b2d9/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-redis/redis v6.15.8+incompatible h1:BKZuG6mCnRj5AOaWJXoCgf6rqTYnYJLe4en2hxT7r9o=
|
||||
github.com/go-redis/redis/v8 v8.0.0-beta.7 h1:4HiY+qfsyz8OUr9zyAP2T1CJ0SFRY4mKFvm9TEznuv8=
|
||||
github.com/go-redis/redis/v8 v8.0.0-beta.7/go.mod h1:FGJAWDWFht1sQ4qxyJHZZbVyvnVcKQN0E3u5/5lRz+g=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U=
|
||||
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/opentracing/opentracing-go v1.1.1-0.20190913142402-a7454ce5950e h1:fI6mGTyggeIYVmGhf80XFHxTupjOexbCppgTNDkv9AA=
|
||||
github.com/opentracing/opentracing-go v1.1.1-0.20190913142402-a7454ce5950e/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I=
|
||||
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/uber/jaeger-client-go v1.6.0 h1:3+zLlq+4npI5fg8IsgAje3YsP7TcEdNzJScyqFIzxEQ=
|
||||
github.com/uber/jaeger-client-go v2.25.0+incompatible h1:IxcNZ7WRY1Y3G4poYlx24szfsn/3LvK9QHCq9oQw8+U=
|
||||
github.com/uber/jaeger-client-go v2.25.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
|
||||
github.com/uber/jaeger-lib v1.5.0 h1:OHbgr8l656Ub3Fw5k9SWnBfIEwvoHQ+W2y+Aa9D1Uyo=
|
||||
github.com/uber/jaeger-lib v2.4.0+incompatible h1:fY7QsGQWiCt8pajv4r7JEvmATdCVaWxXbjwyYwsNaLQ=
|
||||
github.com/uber/jaeger-lib v2.4.0+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
|
||||
go.opentelemetry.io/otel v0.7.0 h1:u43jukpwqR8EsyeJOMgrsUgZwVI1e1eVw7yuzRkD1l0=
|
||||
go.opentelemetry.io/otel v0.7.0/go.mod h1:aZMyHG5TqDOXEgH2tyLiXSUKly1jT3yqE9PmrzIeCdo=
|
||||
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
|
||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20200513190911-00229845015e h1:rMqLP+9XLy+LdbCXHjJHAmTfXCr93W7oruWA6Hq1Alc=
|
||||
golang.org/x/exp v0.0.0-20200513190911-00229845015e/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw=
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191010194322-b09406accb47 h1:/XfQ9z7ib8eEJX2hdgFTZJ/ntt0swNk5oYBziWeTCvY=
|
||||
golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20191009194640-548a555dbc03/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||
google.golang.org/grpc v1.30.0 h1:M5a8xTlYTxwMn5ZFkwhRabsygDY5G8TYLyQDBxJNAxE=
|
||||
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
130
tracing/applications-go/videos-db/appendonly.aof
Normal file
130
tracing/applications-go/videos-db/appendonly.aof
Normal file
@ -0,0 +1,130 @@
|
||||
*2
|
||||
$6
|
||||
SELECT
|
||||
$1
|
||||
0
|
||||
*3
|
||||
$3
|
||||
set
|
||||
$11
|
||||
jM36M39MA3I
|
||||
$206
|
||||
{
|
||||
"id" : "jM36M39MA3I",
|
||||
"title" : "Kubernetes cluster autoscaling",
|
||||
"imageurl" : "https://i.ytimg.com/vi/jM36M39MA3I/sddefault.jpg",
|
||||
"url" : "https://youtu.be/jM36M39MA3I",
|
||||
"description" : ""
|
||||
}
|
||||
|
||||
*3
|
||||
$3
|
||||
set
|
||||
$11
|
||||
FfDI08sgrYY
|
||||
$202
|
||||
{
|
||||
"id" : "FfDI08sgrYY",
|
||||
"title" : "Kubernetes pod autoscaling",
|
||||
"imageurl" : "https://i.ytimg.com/vi/FfDI08sgrYY/sddefault.jpg",
|
||||
"url" : "https://youtu.be/FfDI08sgrYY",
|
||||
"description" : ""
|
||||
}
|
||||
|
||||
*3
|
||||
$3
|
||||
set
|
||||
$11
|
||||
JmCn7k0PlV4
|
||||
$195
|
||||
{
|
||||
"id" : "JmCn7k0PlV4",
|
||||
"title" : "Redis on Kubernetes",
|
||||
"imageurl" : "https://i.ytimg.com/vi/JmCn7k0PlV4/sddefault.jpg",
|
||||
"url" : "https://youtu.be/JmCn7k0PlV4",
|
||||
"description" : ""
|
||||
}
|
||||
|
||||
*3
|
||||
$3
|
||||
set
|
||||
$11
|
||||
_lpDfMkxccc
|
||||
$198
|
||||
{
|
||||
"id" : "_lpDfMkxccc",
|
||||
"title" : "RabbitMQ on Kubernetes",
|
||||
"imageurl" : "https://i.ytimg.com/vi/_lpDfMkxccc/sddefault.jpg",
|
||||
"url" : "https://youtu.be/_lpDfMkxccc",
|
||||
"description" : ""
|
||||
}
|
||||
|
||||
*3
|
||||
$3
|
||||
set
|
||||
$11
|
||||
OFgziggbCOg
|
||||
$183
|
||||
{
|
||||
"id" : "OFgziggbCOg",
|
||||
"title" : "Flux CD",
|
||||
"imageurl" : "https://i.ytimg.com/vi/OFgziggbCOg/sddefault.jpg",
|
||||
"url" : "https://youtu.be/OFgziggbCOg",
|
||||
"description" : ""
|
||||
}
|
||||
|
||||
*3
|
||||
$3
|
||||
set
|
||||
$11
|
||||
myCcJJ_Fk10
|
||||
$184
|
||||
{
|
||||
"id" : "myCcJJ_Fk10",
|
||||
"title" : "Drone CI",
|
||||
"imageurl" : "https://i.ytimg.com/vi/myCcJJ_Fk10/sddefault.jpg",
|
||||
"url" : "https://youtu.be/myCcJJ_Fk10",
|
||||
"description" : ""
|
||||
}
|
||||
|
||||
*3
|
||||
$3
|
||||
set
|
||||
$11
|
||||
2WSJF7d8dUg
|
||||
$183
|
||||
{
|
||||
"id" : "2WSJF7d8dUg",
|
||||
"title" : "Argo CD",
|
||||
"imageurl" : "https://i.ytimg.com/vi/2WSJF7d8dUg/sddefault.jpg",
|
||||
"url" : "https://youtu.be/2WSJF7d8dUg",
|
||||
"description" : ""
|
||||
}
|
||||
|
||||
*3
|
||||
$3
|
||||
set
|
||||
$11
|
||||
QThadS3Soig
|
||||
$196
|
||||
{
|
||||
"id" : "QThadS3Soig",
|
||||
"title" : "Kubernetes on Amazon",
|
||||
"imageurl" : "https://i.ytimg.com/vi/QThadS3Soig/sddefault.jpg",
|
||||
"url" : "https://youtu.be/QThadS3Soig",
|
||||
"description" : ""
|
||||
}
|
||||
|
||||
*3
|
||||
$3
|
||||
set
|
||||
$11
|
||||
eyvLwK5C2dw
|
||||
$244
|
||||
{
|
||||
"id" : "eyvLwK5C2dw",
|
||||
"title" : "Kubernetes on Azure",
|
||||
"imageurl" : "https://i.ytimg.com/vi/eyvLwK5C2dw/mqdefault.jpg?sqp=CISC_PoF&rs=AOn4CLDo7kizrJozB0pxBhxL9JbyiW_EPw",
|
||||
"url" : "https://youtu.be/eyvLwK5C2dw",
|
||||
"description" : ""
|
||||
}
|
BIN
tracing/applications-go/videos-db/configmap.yaml
Normal file
BIN
tracing/applications-go/videos-db/configmap.yaml
Normal file
Binary file not shown.
59
tracing/applications-go/videos-db/deploy.yaml
Normal file
59
tracing/applications-go/videos-db/deploy.yaml
Normal file
@ -0,0 +1,59 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: videos-db
|
||||
labels:
|
||||
app: videos-db
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: videos-db
|
||||
replicas: 1
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: videos-db
|
||||
spec:
|
||||
initContainers:
|
||||
- name: data
|
||||
image: busybox
|
||||
command: [ "sh", "-c" ]
|
||||
args:
|
||||
- |
|
||||
cp /config/appendonly.aof /tmp/appendonly.aof
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /tmp/
|
||||
- name: config
|
||||
mountPath: /config/
|
||||
containers:
|
||||
- name: videos-db
|
||||
image: redis:6.0-alpine
|
||||
ports:
|
||||
- containerPort: 6379
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /tmp/
|
||||
command: [ "redis-server"]
|
||||
args: ["--dir", "/tmp", "--appendonly", "yes"]
|
||||
volumes:
|
||||
- name: data
|
||||
emptyDir: {}
|
||||
- name: config
|
||||
configMap:
|
||||
name: videos-db
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: videos-db
|
||||
labels:
|
||||
app: videos-db
|
||||
spec:
|
||||
type: ClusterIP
|
||||
selector:
|
||||
app: videos-db
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 6379
|
||||
targetPort: 6379
|
12
tracing/applications-go/videos-web/bootstrap.min.css
vendored
Normal file
12
tracing/applications-go/videos-web/bootstrap.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
62
tracing/applications-go/videos-web/deploy.yaml
Normal file
62
tracing/applications-go/videos-web/deploy.yaml
Normal file
@ -0,0 +1,62 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: videos-web
|
||||
labels:
|
||||
app: videos-web
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: videos-web
|
||||
replicas: 1
|
||||
strategy:
|
||||
type: RollingUpdate
|
||||
rollingUpdate:
|
||||
maxSurge: 1
|
||||
maxUnavailable: 0
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: videos-web
|
||||
spec:
|
||||
containers:
|
||||
- name: videos-web
|
||||
image: aimvector/jaeger-tracing:videos-web-1.0.0
|
||||
imagePullPolicy : Always
|
||||
ports:
|
||||
- containerPort: 80
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: videos-web
|
||||
labels:
|
||||
app: videos-web
|
||||
spec:
|
||||
type: ClusterIP
|
||||
selector:
|
||||
app: videos-web
|
||||
ports:
|
||||
- protocol: TCP
|
||||
name: http
|
||||
port: 80
|
||||
targetPort: 80
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1beta1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
annotations:
|
||||
kubernetes.io/ingress.class: "nginx"
|
||||
nginx.ingress.kubernetes.io/ssl-redirect: "false"
|
||||
nginx.ingress.kubernetes.io/rewrite-target: /$2
|
||||
name: videos-web
|
||||
spec:
|
||||
rules:
|
||||
- host: tracing.demo
|
||||
http:
|
||||
paths:
|
||||
- path: /home(/|$)(.*)
|
||||
backend:
|
||||
serviceName: videos-web
|
||||
servicePort: 80
|
||||
|
8
tracing/applications-go/videos-web/dockerfile
Normal file
8
tracing/applications-go/videos-web/dockerfile
Normal file
@ -0,0 +1,8 @@
|
||||
FROM nginx:1.19-alpine
|
||||
|
||||
#config
|
||||
COPY ./nginx.conf /etc/nginx/nginx.conf
|
||||
|
||||
#content
|
||||
COPY ./*.html /usr/share/nginx/html/
|
||||
COPY ./*.css /usr/share/nginx/html/
|
96
tracing/applications-go/videos-web/index.html
Normal file
96
tracing/applications-go/videos-web/index.html
Normal file
@ -0,0 +1,96 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<link rel="stylesheet" href="bootstrap.min.css">
|
||||
<title>Video Catalog</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
|
||||
<article>
|
||||
<div ng-app="videos" ng-controller="videosController" class="container">
|
||||
<div class="row">
|
||||
<div id="accordion">
|
||||
|
||||
<div id="{{ l.id }}" ng-repeat="l in playlist" class="card">
|
||||
|
||||
<div class="card-header" id="heading{{ l.id }}">
|
||||
<h5 class="mb-0" style="text-align: center;">
|
||||
<button class="btn btn-link" data-toggle="collapse" data-target="#collapse{{ l.id }}" aria-expanded="true"
|
||||
aria-controls="collapse{{ l.id }}">
|
||||
{{ l.name }}
|
||||
</button>
|
||||
</h5>
|
||||
</div>
|
||||
|
||||
<div id="collapse{{ l.id }}" class="collapse show" aria-labelledby="heading{{ l.id }}" data-parent="#accordion">
|
||||
<div class="card-body">
|
||||
|
||||
<div class="row">
|
||||
<div class="col card" ng-repeat="v in l.videos" style="width: 18rem;">
|
||||
<img class="card-img-top" src="{{ v.imageurl }}" alt="Card image cap">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">{{ v.title }}</h5>
|
||||
<p class="card-text">{{ v.description }}</p>
|
||||
<a href="{{ v.url }}" class="btn btn-primary">Watch</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</article>
|
||||
|
||||
<hr />
|
||||
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
|
||||
|
||||
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js"
|
||||
integrity="sha384-uefMccjFJAIv6A+rW+L4AHf99KvxDjWSu1z9VI8SKNVmz4sk7buKt/6v9KI65qnm"
|
||||
crossorigin="anonymous"></script>
|
||||
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
|
||||
|
||||
<script>
|
||||
|
||||
var model = {
|
||||
playlist: [],
|
||||
};
|
||||
|
||||
var playlistApiUrl = "";
|
||||
if (location.hostname == "localhost"){
|
||||
playlistApiUrl = "http://localhost:81/"
|
||||
} else {
|
||||
playlistApiUrl = "http://" + location.hostname + "/api/playlists"
|
||||
}
|
||||
|
||||
var app = angular.module('videos', []);
|
||||
app.controller('videosController', function ($scope, $http) {
|
||||
|
||||
$http.get(playlistApiUrl)
|
||||
.then(function (response) {
|
||||
|
||||
console.log(response);
|
||||
//$scope.model = model;
|
||||
for (i = 0; i < response.data.length; ++i) {
|
||||
model.playlist.push(response.data[i]);
|
||||
}
|
||||
$scope.playlist = response.data;
|
||||
});
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
35
tracing/applications-go/videos-web/nginx.conf
Normal file
35
tracing/applications-go/videos-web/nginx.conf
Normal file
@ -0,0 +1,35 @@
|
||||
user nginx;
|
||||
worker_processes 1;
|
||||
|
||||
error_log /var/log/nginx/error.log warn;
|
||||
pid /var/run/nginx.pid;
|
||||
|
||||
events {
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
http {
|
||||
include /etc/nginx/mime.types;
|
||||
default_type application/octet-stream;
|
||||
|
||||
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
|
||||
'$status $body_bytes_sent "$http_referer" '
|
||||
'"$http_user_agent" "$http_x_forwarded_for"';
|
||||
access_log /var/log/nginx/access.log main;
|
||||
server {
|
||||
listen 80;
|
||||
|
||||
location / {
|
||||
gzip off;
|
||||
root /usr/share/nginx/html/;
|
||||
index index.html;
|
||||
#index index-v2.html;
|
||||
}
|
||||
|
||||
location ~* \.(js|jpg|png|css)$ {
|
||||
root /usr/share/nginx/html/;
|
||||
}
|
||||
}
|
||||
sendfile on;
|
||||
keepalive_timeout 65;
|
||||
}
|
66
tracing/docker-compose.yaml
Normal file
66
tracing/docker-compose.yaml
Normal file
@ -0,0 +1,66 @@
|
||||
version: "3.4"
|
||||
services:
|
||||
videos-web:
|
||||
container_name: videos-web
|
||||
image: aimvector/jaeger-tracing:videos-web-1.0.0
|
||||
build:
|
||||
context: ./applications-go/videos-web
|
||||
ports:
|
||||
- 80:80
|
||||
networks:
|
||||
- tracing
|
||||
playlists-api:
|
||||
container_name: playlists-api
|
||||
image: aimvector/jaeger-tracing:playlists-api-1.0.0
|
||||
build:
|
||||
context: ./applications-go/playlists-api
|
||||
environment:
|
||||
- "ENVIRONMENT=DEBUG"
|
||||
- "REDIS_HOST=playlists-db"
|
||||
- "REDIS_PORT=6379"
|
||||
ports:
|
||||
- 81:10010
|
||||
networks:
|
||||
- tracing
|
||||
playlists-db:
|
||||
container_name: playlists-db
|
||||
image: redis:6.0-alpine
|
||||
command: [ "redis-server" , "--dir", "/tmp", "--appendonly", "yes"]
|
||||
volumes:
|
||||
- ./applications-go/playlists-db/appendonly.aof:/tmp/appendonly.aof
|
||||
networks:
|
||||
- tracing
|
||||
videos-api:
|
||||
container_name: videos-api
|
||||
image: aimvector/jaeger-tracing:videos-api-1.0.0
|
||||
build:
|
||||
context: ./applications-go/videos-api
|
||||
environment:
|
||||
- "ENVIRONMENT=DEBUG"
|
||||
- "REDIS_HOST=videos-db"
|
||||
- "REDIS_PORT=6379"
|
||||
#- "DELAY=true"
|
||||
#- "FLAKY=true"
|
||||
ports:
|
||||
- 82:10010
|
||||
networks:
|
||||
- tracing
|
||||
videos-db:
|
||||
container_name: videos-db
|
||||
image: redis:6.0-alpine
|
||||
command: [ "redis-server" , "--dir", "/tmp", "--appendonly", "yes"]
|
||||
volumes:
|
||||
- ./applications-go/videos-db/appendonly.aof:/tmp/appendonly.aof
|
||||
networks:
|
||||
- tracing
|
||||
jaeger:
|
||||
container_name: jaeger
|
||||
image: jaegertracing/all-in-one:latest
|
||||
networks:
|
||||
- tracing
|
||||
ports:
|
||||
- 16686:16686
|
||||
- 14269:14269
|
||||
networks:
|
||||
tracing:
|
||||
name: tracing
|
Loading…
x
Reference in New Issue
Block a user