Giter Club home page Giter Club logo

service's Introduction

Ultimate Software Design with Kubernetes

CircleCI Go Report Card go.mod Go version

InsightsSnapshot

Copyright 2018, 2019, 2020, 2021, 2022, 2023, 2024 Ardan Labs
[email protected]

My Information

Name:    Bill Kennedy  
Company: Ardan Labs  
Title:   Managing Partner  
Email:   [email protected]  
Twitter: goinggodotnet  

Description

"As a program evolves and acquires more features, it becomes complicated, with subtle dependencies between components. Over time, complexity accumulates, and it becomes harder and harder for programmers to keep all the relevant factors in their minds as they modify the system. This slows down development and leads to bugs, which slow development even more and add to its cost. Complexity increases inevitably over the life of any program. The larger the program, and the more people that work on it, the more difficult it is to manage complexity." - John Ousterhout

The service starter kit is a starting point for building production grade scalable web service applications that leverage the power of a Domain Driven, Data Oriented Architecture that can run in Kubernetes. The goal of this project is to provide a proven starting point that reduces the repetitive tasks required for a new project to be launched into production. It uses minimal dependencies, implements idiomatic code and follows Go best practices. Collectively, the project lays out everything logically to minimize guess work and enable engineers to quickly maintain a mental model for the project.

The class behind this starter kit teaches how to build production-level software in Go leveraging the power of a Domain Driven, Data Oriented Architecture that can run in Kubernetes. From the beginning, you will pair program with the instructor walking through the design philosophies and guidelines for building software in Go. With each new feature that is added to the project, you will learn how to deploy to and manage the Kubernetes environment used to run the project. The core of this class is to teach you and your team how to handle and reduce the spread of complexity in the systems you are building.

Learn more about the project:

Wiki | Course Outline | Class Schedule

Licensing

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.

Learn More

Reach out about corporate training events, open enrollment live training sessions, and on-demand learning options.

Ardan Labs (www.ardanlabs.com)
[email protected]

Index

Installation

To clone the project, create a folder and use the git clone command. Then please read the makefile file to learn how to install all the tooling and docker images.

$ cd $HOME
$ mkdir code
$ cd code
$ git clone https://github.com/ardanlabs/service or [email protected]:ardanlabs/service.git
$ cd service

Create Your Own Version

If you want to create a version of the project for your own use, use the new gonew command.

$ go install golang.org/x/tools/cmd/gonew@latest

$ cd $HOME
$ mkdir code
$ cd code
$ gonew github.com/ardanlabs/service github.com/mydomain/myproject
$ cd myproject
$ go mod vendor

Now you have a copy with your own module name. Now all you need to do is initialize the project for git.

Running The Project

To run the project use the following commands.

# Install Tooling
$ make dev-gotooling
$ make dev-brew
$ make dev-docker

# Run Tests
$ make test

# Shutdown Tests
$ make test-down

# Run Project
$ make dev-up
$ make dev-update-apply
$ make token
$ export TOKEN=<COPY TOKEN>
$ make users

# Run Load
$ make load

# Run Tooling
$ make grafana
$ make statsviz

# Shut Project
$ make dev-down

Purchase Video

The entire training class has been recorded to be made available to those who can't have the class taught at their company or who can't attend a conference. This is the entire class material.

ardanlabs.com/education

Our Experience

We have taught Go to thousands of developers all around the world since 2014. There is no other company that has been doing it longer and our material has proven to help jump-start developers 6 to 12 months ahead of their knowledge of Go. We know what knowledge developers need in order to be productive and efficient when writing software in Go.

Our classes are perfect for intermediate-level developers who have at least a few months to years of experience writing code in Go. Our classes provide a very deep knowledge of the programming langauge with a big push on language mechanics, design philosophies and guidelines. We focus on teaching how to write code with a priority on consistency, integrity, readability and simplicity. We cover a lot about “if performance matters” with a focus on mechanical sympathy, data oriented design, decoupling and writing/debugging production software.

Our Teacher

William Kennedy (@goinggodotnet)

William Kennedy is a managing partner at Ardan Labs in Miami, Florida. Ardan Labs is a high-performance development and training firm working with startups and fortune 500 companies. He is also a co-author of the book Go in Action, the author of the blog GoingGo.Net, and a founding member of GoBridge which is working to increase Go adoption through diversity.

Video Training
Ultimate Go Video
Ardan Labs YouTube Channel

Blog
Going Go

Writing
Running MongoDB Queries Concurrently With Go
Go In Action

Articles
IT World Canada

Video
Golang Charlotte (2024) - Domain Driven, Data Oriented Architecture
GopherCon SG (2023) - K8s CPU Limits and Go
P99 Talk (2022) - Evaluating Performance In Go
GopherCon Europe (2022) - Practical Memory Profiling
Dgrpah Day (2021) - Getting Started With Dgraph and GraphQL
GDN Event #1 (2021) - GoBridge Needs Your Help
Training Within The Go Community (2019)
GopherCon Australia (2019) - Modules
Golab (2019) - You Want To Build a Web Service?
GopherCon Singapore (2019) - Garbage Collection Semantics
GopherCon India (2019) - Channel Semantics
GoWayFest Minsk (2018) - Profiling Web Apps
GopherCon Singapore (2018) - Optimizing For Correctness
GopherCon India (2018) - What is the Legacy You Are Leaving Behind
Code::Dive (2017) - Optimizing For Correctness
Code::Dive (2017) - Go: Concurrency Design
dotGo (2017) - Behavior Of Channels
GopherCon Singapore (2017) - Escape Analysis
Capital Go (2017) - Concurrency Design
GopherCon India (2017) - Package Oriented Design
GopherCon India (2015) - Go In Action
GolangUK (2016) - Dependency Management
GothamGo (2015) - Error Handling in Go
GopherCon (2014) - Building an analytics engine

Golang Charlotte (2023) - Domain Driven, Data Oriented Architecture with Bill Kennedy
Prague Meetup (2021) - Go Module Engineering Decisions
Practical Understanding Of Scheduler Semantics (2021)
Go Generics Draft Proposal (2020)
Hack Potsdam (2017) - Tech Talk with William Kennedy
Chicago Meetup (2016) - An Evening
Vancouver Meetup (2016) - Go Talk & Ask Me Anything With William Kennedy
Vancouver Meetup (2015) - Compiler Optimizations in Go
Bangalore Meetup (2015) - OOP in Go
GoSF Meetup - The Nature of Constants in Go
London Meetup - Mechanical Sympathy
Vancouver Meetup - Decoupling From Change

Podcasts
Ardan Labs Podcast: On Going Series
Encore, domain design in Go with Bill Kennedy
Mangtas Nation: A Golang Deep Dive with Bill Kennedy
Coding with Holger: Go with Bill Kennedy
Craft of Code: From Programming to Teaching Code with Bill Kennedy
GoTime: Design Philosophy
GoTime: Learning and Teaching Go
GoTime: Bill Kennedy on Mechanical Sympathy
GoTime: Discussing Imposter Syndrome
HelloTechPros: Your Tech Interviews are Scaring Away Brilliant People
HelloTechPros: The 4 Cornerstones of Writing Software

More About Go

Go is an open source programming language that makes it easy to build simple, reliable, and efficient software. Although it borrows ideas from existing languages, it has a unique and simple nature that make Go programs different in character from programs written in other languages. It balances the capabilities of a low-level systems language with some high-level features you see in modern languages today. This creates a programming environment that allows you to be incredibly productive, performant and fully in control; in Go, you can write less code and do so much more.

Go is the fusion of performance and productivity wrapped in a language that software developers can learn, use and understand. Go is not C, yet we have many of the benefits of C with the benefits of higher level programming languages.

The Ecosystem of the Go Programming Language - Henrique Vicente
The Why of Go - Carmen Andoh
Go Ten Years and Climbing - Rob Pike
The eigenvector of "Why we moved from language X to language Y" - Erik Bernhardsson
Learn More - Go Team
Simplicity is Complicated - Rob Pike
Getting Started In Go - Aarti Parikh

Minimal Qualified Student

The material has been designed to be taught in a classroom environment. The code is well commented but missing some contextual concepts and ideas that will be covered in class. Students with the following minimal background will get the most out of the class.

  • Studied CS in school or has a minimum of two years of experience programming full time professionally.
  • Familiar with structural and object oriented programming styles.
  • Has worked with arrays, lists, queues and stacks.
  • Understands processes, threads and synchronization at a high level.
  • Operating Systems
    • Has worked with a command shell.
    • Knows how to maneuver around the file system.
    • Understands what environment variables are.

Joining the Go Slack Community

We use a Slack channel to share links, code, and examples during the training. This is free. This is also the same Slack community you will use after training to ask for help and interact with may Go experts around the world in the community.

  1. Using the following link, fill out your name and email address: https://invite.slack.gobridge.org
  2. Check your email, and follow the link to the slack application.
  3. Join the training channel by clicking on this link: https://gophers.slack.com/messages/training/
  4. Click the “Join Channel” button at the bottom of the screen.

All material is licensed under the Apache License Version 2.0, January 2004.

service's People

Contributors

abtris avatar ardan-bkennedy avatar bhechinger avatar bruno-10 avatar burhan avatar cip8 avatar dependabot[bot] avatar dlsniper avatar haibin avatar hallabro avatar himynamej avatar ioagel avatar jcbwlkr avatar johnharris85 avatar jpreese avatar jtrinh27 avatar kinluek avatar levikobi avatar liyongjing avatar michalnicp avatar mrkagelui avatar nhaancs avatar nstogner avatar oussamm avatar pendolf avatar runar-rkmedia avatar sheimyrahman avatar ssenthil416 avatar stephenwithav avatar sudomateo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

service's Issues

Authorization

Implement authorization using the claims that get parsed from JWT.

pull access denied for sales-api

Just curious, is the sales-api accessible, because I'm getting the following after running make up:

pull access denied for sales-api-amd64, repository does not exist or may require 'docker login'

Thanks

Break Project Down As Training Material

I had started this repo quickly for a training earlier this year.

https://github.com/ardanlabs/srvtraining

I think the code needs to be broken down into consumable parts. It's hard in the classroom to copy and paste the code and clean it up. It would be nice to have exercises in between to allow people to get comfortable as you add more complexity.

Thoughts?

Distributed logging

There is a mention in readme that project contains the feature of

  • Distributed logging

but as far as I understand there is a simple logger that writes to stdout and nothing more. Do you consider to achieve distributed logging by adding some logging driver to docker-compose or another way?

Put logic around logging with expanded details

Right now internal/mid/errors.go logs the errors it receives using %+v. If the error in question was wrapped with pkg/errors then it will print a stack trace.

This is good for unexpected errors but rather annoying for normal errors like a bad request. For example if someone tries to make a product with a quantity of -10 I don't need to see a whole stack trace.

Authentication

We need to add a minimal but complete layer for authentication and authorization.

Flag package incompatible with non-flag arguments

Appear unable to do: go run main.go something.txt ... i.e. reading a standard non-flag argument b/c a call to flag.Process errors out on the default:

internal/platform/flag/flag.go

		switch {
		case strings.HasPrefix(osArg, "-test"):
			return nil
		case strings.HasPrefix(osArg, "--"):
			flag = osArg[2:]
		case strings.HasPrefix(osArg, "-"):
			flag = osArg[1:]
		default:
			return fmt.Errorf("invalid command line %q", osArg)
		}

Remove GOPATH dependency

Our Go code should all work with modules in 1.11 and be buildable outside of GOPATH. The problem is some of our tooling like the makefile have explicit dependencies on GOPATH. Remove those.

K8s : Supprt for MiniKube and Skaffold

Skaffold is a tool that makes developing applications for kubernetes easier. It supports a live-reload development mode where it watches for changes to code and will trigger docker builds / kubectl apply's (really handy when using minikube during local development). It also can be used to simplify build/deploy pipelines. Check it out:

https://skaffold.dev/docs/#demo

Paginate lists

In many APIs I've developed we have List endpoints but they don't return the entire collection just a single page of records. We should discuss if this is worth implementing in service.

Integrate Authz OPA - Open Policy Agent

I think it will be good if we can add authz into the service. I think this is important part of any system and OPA is really interesting product and it is part of CNCF and OPA has integration with lot of popular product like Kubernetes and isto etc.

OPA is a lightweight general-purpose policy engine that can be co-located with service.

https://www.openpolicyagent.org

Initial 'make' fails b/c of missing private.pem

Initial make fails with:

Step 10/27 : COPY private.pem private.pem
COPY failed: stat /var/lib/docker/tmp/docker-builder401590106/private.pem: no such file or directory
makefile:20: recipe for target 'sales-api' failed

Steps to reproduce:

  1. git clone --depth 1 https://github.com/ardanlabs/service.git
  2. cd service/ && make

AutoClose for file system

If I add the fileSystem with http.Handle in the routes, is it autoClosed when shutdown the API?

// routes.go

func API(shutdown chan os.Signal, log *log.Logger, db *sqlx.DB, authenticator *auth.Authenticator) http.Handler {

	app := web.NewApp(shutdown, mid.Logger(log), mid.Errors(log), mid.Metrics(), mid.Panics(log))

	check := Check{
		db: db,
	}
	app.Handle("GET", "/v1/health", check.Health)
        ...

	http.Handle("/files", http.FileServer(http.Dir(uploadPath)))  // This line

	return app
}

Intermittent failure in trace tests

There is an intermittent failure in the tests for internal/platform/trace. If you look at the build output for this https://circleci.com/gh/ardanlabs/service/19 it failed but when I restarted the build it passed.

The tests say

trace_test.go:69:     Test: 2    When running test: SendOnTime
trace_test.go:99:     ✓    Should have zero spans.
trace_test.go:112:     ✓    Should have a batch to send.
trace_test.go:117:         Got : [0xc1fbe0 0xc1fcc0]
trace_test.go:118:         Want: [0xc1fb00 0xc1fbe0 0xc1fcc0]
trace_test.go:119:     ✗    Should have an expected match of the batch to send.

JWT Generation

Add a CLI or API endpoint to demonstrate token generation.

Update cfg to add flags to the command line

Peter Bourgon in his talk at Iceland made a point that services should have flags for all possible configuration options. This helps operation and with documentation. The cfg package should add the support for this since it is a single place for configuration knowledge.

Database pointer on handler level

In the handler, you defined:

// Product represents the Product API method handler set.
type Product struct {
	db *sqlx.DB

	// ADD OTHER STATE LIKE THE LOGGER IF NEEDED.
}

What's the reasoning behind having a database access to be passed down the call stack? Also, why not having a dedicated layer, repository, to manage all the queries to the db?

Use official docker client instead of os/exec

Specifically talking about internal/platform/docker/docker.go
I see that we use os/exec to pipe out commands to docker. This works right now, but if commands start getting more complex, it's going to get dirty.
Docker has an excellent official client which I believe would make this a lot cleaner. The README claims that docker is going to be an integral part. If so, I think having this as a dependency should not be an issue.
https://godoc.org/github.com/docker/docker/client

I'm happy to submit a PR if you like.

Consider adding an IDL (OpenAPI / Swagger)

Having some sort of interface definition is extremely useful as it provides a clear API contract for clients. For a REST API this should probably follow the OpenAPI spec (https://en.wikipedia.org/wiki/OpenAPI_Specification).

Usually there is some sort of automated link between the server's codebase and the IDL. This can be one of two directions: code generated from IDL or IDL generated from code. A few thoughts on each direction:

  1. IDL --> Code: OpenAPI/swagger docs are a pain to write IMO (I much prefer gRPC's protobuf IDL as it is very clean IMO). This route may limit package-structure choices.
  2. Code --> IDL: Last I checked the go swagger tool generates the JSON IDL off of code comments. It was brittle from my experience b/c it elevated comments to a level where they had side-effects that could influence production systems.

These items should be tackled sooner rather than later b/c if we choose to link the codebase and IDL in some automated way, it has big implications on the project's code structure.

Docker Change Proposal

My first proposal is that the dockerfiles be moved out of the root. We can get away with it with only 3 services, but the more services you have the messier the root is going to be.

I have a suggestion on how I would structure it, drawn inspiration from previous client projects and my own personal projects:

cmd/
	sales-api/
		deploy/
			Dockerfile
			apiary.apib
			DEPLOY.md
	sidecar/
		metrics/
			deploy/
				Dockerfile
				apiary.apib
				DEPLOY.md
		tracer/
			deploy/
				Dockerfile
				apiary.apib
				DEPLOY.md
internal/
docker-compose.yml
makefile

I've ommitted a decent amount of file structure above, but that should be enough to see what I'm proposing. The deploy folder can be found in each program's directory. The deploy folder contains the Dockerfile (most important) and maybe some documentation related to the service/environment needed for deployment (examples being apiary.apib and DEPLOY.md)

Current the compose file is fine the way it is, the Dockerfiles would, however, have to be changed. I like the idea behind using a container to not only run the program, but also build it. Makes deployment even more trivial. I normally do not do this. I normally build the binary and only use docker to host it, automated through makefile rules, and link the containers in a network through compose. This Dockerfiles really easy to read, trivial, and fast. In order to keep building the way they are currently built, you'll have to make minor modifications to the Dockerfiles and build from the root, allowing the build context to be in a place where it can properly copy all the files.


My second proposal is pretty simple, make a dockerignore and clean up the COPY commands. I noticed we were blindly copying the entire contents of the project into each image to build. We really only need the module files, internal/ and the specific cmd/ subfolder for the requested service.

Add environment provisioning and setup

We need to create a script / tool that will provision the Digital Ocean (for now) infra required and install kubernetes ready for the service to be deployed to:

  • Create script to setup k8s automatically (probably a modified version of this guide
  • Create script (Terraform?) to provision the infra and bootstrap the above

Proposal: unexport the `auth.Key`

Currently auth.Key is only used to retrieve the Claims from the current Context:

claims, ok := ctx.Value(auth.Key).(auth.Claims)

I t could be made unexported (key) by adding of two small helpers in the auth package:

// ClaimsValue extract the Claims from the context
func ClaimsValuectx context.Context) (Claims, bool) {
	claims, ok := ctx.Value(key).(Claims)
	return claims, ok
}

// WithClaims add the Claims to the context
func WithClaims(ctx context.Context, claims Claims) context.Context {
	return context.WithValue(ctx, key, claims)
}

Which would be used like this:

claims, ok := auth.ClaimsValue(ctx)

If you think this approach could make sense, I would be happy to make a PR

Consider cleaning up the .git folder to reduce the repo size

A fresh clone currently takes a good amount of time because of binary files in the commit history.

You can identify them by running this oneliner: git rev-list --objects --all | grep -f <(git verify-pack -v .git/objects/pack/*.idx| sort -k 3 -n | cut -f 1 -d " " | tail -10)

1930a9b3151f0dd2b3ff245b9f77fb83407ede70 cmd/search/search
728a7a93403083b8fd06accde6c79d6ed8cd82a4 cmd/search/search
41265c8f26433009e979fa88ca50fa5395dc734a cmd/sidecar/metrics/metrics
8ba505fcf5bad430d4e3e7df1a9b38802260c9a2 cmd/sidecar/metrics/metrics
90a30e0e48d378088c3a594688da3b5a2b785ce3 cmd/sidecar/metrics/metrics
e82d16d2e603ec8b6f58aef127d871331c150306 cmd/crud/crud
97e1a3e5cf9b86726d960fb30d8cf05189cb681b cmd/crud/crud
fc933685fe478c4686f4733e4f8d01242906cc1e cmd/crud/crud
218ad79408ee5e4e2f71748ecccfc8e1d4f54133 cmd/crud/crud
099217f9bae311d3159d43af64e2ccac8076d315 cmd/crud/crud

Filename Git id

crud | 218ad794 (7,6 MB), 099217f9 (7,6 MB), ...
metrics | 90a30e0e (5,8 MB), 8ba505fc (6,2 MB), 41265c8f (6,2 MB)
search | 1930a9b3 (11,8 MB), 728a7a93 (12,4 MB)

Pick a theme

The material would be easier to digest if our main service wasn't simply crud and if we were manipulating records besides just User. Some ideas include:

  • A TODO service where we are manipulating Task values.
  • A veterinarian's office service where we have Pet values.
  • A comic collector's database. Let people keep track of their Comics.
  • A garage sale manager. I want to know what Products I have for sale in my garage, how much they cost, and who they came from. Many people do multi-family sales and it could be useful to know that item 12345 came from Cindy so the money should go to her.

We could probably come up with several and bikeshed this forever.

Wrong GitHub link in README

### Getting the project
...
$ go get -u github.com/ardanlabs/gotraining

Should be

### Getting the project
...
$ go get -u github.com/ardanlabs/service

K8s Support

We need to add support for deploying to k8s. @jcbwlkr has a great idea of giving students a droplet on DO with a k8s environment already setup. We don't need to teach installing k8s but deplopying to it. Though this has a cost per student in each class, it is minimal and worth it.

We need to setup a k8s image and have instructions for creating a student lab environment.
Then teach how to deploy.

Package API vs Service API Philosophy

I have found that some companies lack a well defined philosophy on how to expose functionality... i.e. I need to develop functionality X: do I expose it as a shared library or a endpoint on a service? Perhaps we could define a philosophy on this topic as a part of this service / course?

Proposal: Keys generation

It is normaly not an issue but just to my point of view a simple recomendation. To build the project a private key private.pem should be provided so in the makefile it would be better maybe to generate the private key automatically.
My example in the makefile

all: keys sales-api metrics up

Question: How to get the Search UI served?

Hi Bill,

On the search branch I bootstrapped the services with make up and browsing the health endpoint works fine using http://0.0.0.0:5000/health

But what endpoint to hit for getting the search.html displayed?

cmd/search/internal/handlers/routes.go shows that /static/ is stripped away from the path, so my guess is that http://0.0.0.0:5000/ should serve the UI but I currently get 404 for that.
Same for http://0.0.0.0:5000/css/main.css

SEARCH : 2020/02/20 17:28:00.746631 main.go:78: main : Started : Application Initializing version "c391787a78543663191e11e4f555e02c9f3e55a7"
SEARCH : 2020/02/20 17:28:00.746709 main.go:85: main : Config :
--web-api-host=0.0.0.0:5000
--web-debug-host=0.0.0.0:6000
--web-read-timeout=5s
--web-write-timeout=5s
--web-shutdown-timeout=5s
--zipkin-local-endpoint=0.0.0.0:5000
--zipkin-reporter-uri=http://zipkin:9411/api/v2/spans
--zipkin-service-name=search
--zipkin-probability=0.05
SEARCH : 2020/02/20 17:28:00.746726 main.go:102: main : Started : Initializing zipkin tracing support
SEARCH : 2020/02/20 17:28:00.746831 main.go:95: main : Debug Listening 0.0.0.0:6000
SEARCH : 2020/02/20 17:28:00.747080 main.go:150: main : API Listening 0.0.0.0:5000
SEARCH : 2020/02/20 17:31:59.074752 logger.go:34: d3d41c829cb0d6ea83aed5b97bc624e9 : (500) : GET /search -> 192.168.48.1:35650 (1.299281ms)
SEARCH : 2020/02/20 20:10:29.941274 logger.go:34: 7761c6e16a413deb561770312fb6877d : (200) : GET /health -> 192.168.48.1:48664 (33.701µs)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.