Skip to content

Commit

Permalink
Explicit plugins (#81)
Browse files Browse the repository at this point in the history
* Add explicit-load versions of plugins

The existing aws plugins install their metadata at package load
time. They aren't meant to be loaded in test/development environments,
but there is no good way to only load them in production since you
can't conditionally load a package.

- move the plugins under a new /awsplugins path and change init() to
  Init() so user must explicitly call a method to load the plugin.
- leave the old plugins in place, delegating to the new plugins. i
  also left the "Origin" constants since those are part of the
  packages' public APIs.

* Add myself to contributors

* Add README.md note about new plugins
  • Loading branch information
Muir Manders authored and luluzhao committed Jan 31, 2019
1 parent 5b556db commit 0aa94d4
Show file tree
Hide file tree
Showing 8 changed files with 154 additions and 79 deletions.
1 change: 1 addition & 0 deletions CONTRIBUTORS.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ The following people have contributed to the AWS X-Ray SDK for Go's design and/o
* Bilal Khan
* James Bowman
* Lulu Zhao
* Muir Manders
* Raymond Lin
* Rohit Banga
27 changes: 25 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ If you also want to install SDK's testing dependencies. They can be installed us
go get -u -t github.com/aws/aws-xray-sdk-go/...
```

You may also use [Glide](https://github.com/Masterminds/glide) to manage dependencies by using
You may also use [Glide](https://github.com/Masterminds/glide) to manage dependencies by using

```
glide install
Expand Down Expand Up @@ -175,11 +175,34 @@ func HandleRequest(ctx context.Context, name string) (string, error) {
if err != nil {
return name, err
}

return fmt.Sprintf("Hello %s!", name), nil
}
```

**Plugins**

The plugins under "github.com/aws/aws-xray-sdk-go/plugins/" are activated at package load time. This can be convenient in some cases, but often you want to load them conditionally at runtime (e.g. don't load in tests). For this purpose, there is a new set of plugins under "github.com/aws/aws-xray-sdk-go/awsplugins/" that have an explicit `Init()` function you must call to load the plugin:

```go
import (
"os"

"github.com/aws/aws-xray-sdk-go/awsplugins/ec2"
"github.com/aws/aws-xray-sdk-go/xray"
)

func init() {
// conditionally load plugin
if os.Getenv("ENVIRONMENT") == "production" {
ec2.Init()
}

xray.Configure(xray.Config{
ServiceVersion: "1.2.3",
})
}
```

## License

Expand Down
45 changes: 45 additions & 0 deletions awsplugins/beanstalk/beanstalk.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Copyright 2017-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. A copy of the License is located at
//
// http://aws.amazon.com/apache2.0/
//
// or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

package beanstalk

import (
"encoding/json"
"io/ioutil"

"github.com/aws/aws-xray-sdk-go/internal/plugins"
log "github.com/cihub/seelog"
)

const Origin = "AWS::ElasticBeanstalk::Environment"

func Init() {
if plugins.InstancePluginMetadata != nil && plugins.InstancePluginMetadata.BeanstalkMetadata == nil {
addPluginMetadata(plugins.InstancePluginMetadata)
}
}

func addPluginMetadata(pluginmd *plugins.PluginMetadata) {
ebConfigPath := "/var/elasticbeanstalk/xray/environment.conf"

rawConfig, err := ioutil.ReadFile(ebConfigPath)
if err != nil {
log.Errorf("Unable to read Elastic Beanstalk configuration file %s: %v", ebConfigPath, err)
return
}

config := &plugins.BeanstalkMetadata{}
err = json.Unmarshal(rawConfig, config)
if err != nil {
log.Errorf("Unable to unmarshal Elastic Beanstalk configuration file %s: %v", ebConfigPath, err)
return
}

pluginmd.BeanstalkMetadata = config
pluginmd.Origin = Origin
}
41 changes: 41 additions & 0 deletions awsplugins/ec2/ec2.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Copyright 2017-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. A copy of the License is located at
//
// http://aws.amazon.com/apache2.0/
//
// or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

package ec2

import (
"github.com/aws/aws-sdk-go/aws/ec2metadata"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-xray-sdk-go/internal/plugins"
log "github.com/cihub/seelog"
)

const Origin = "AWS::EC2::Instance"

func Init() {
if plugins.InstancePluginMetadata != nil && plugins.InstancePluginMetadata.EC2Metadata == nil {
addPluginMetadata(plugins.InstancePluginMetadata)
}
}

func addPluginMetadata(pluginmd *plugins.PluginMetadata) {
session, e := session.NewSession()
if e != nil {
log.Errorf("Unable to create a new ec2 session: %v", e)
return
}
client := ec2metadata.New(session)
doc, err := client.GetInstanceIdentityDocument()
if err != nil {
log.Errorf("Unable to read EC2 instance metadata: %v", err)
return
}

pluginmd.EC2Metadata = &plugins.EC2Metadata{InstanceID: doc.InstanceID, AvailabilityZone: doc.AvailabilityZone}
pluginmd.Origin = Origin
}
36 changes: 36 additions & 0 deletions awsplugins/ecs/ecs.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright 2017-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. A copy of the License is located at
//
// http://aws.amazon.com/apache2.0/
//
// or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

package ecs

import (
"os"

"github.com/aws/aws-xray-sdk-go/internal/plugins"
log "github.com/cihub/seelog"
)

const Origin = "AWS::ECS::Container"

func Init() {
if plugins.InstancePluginMetadata != nil && plugins.InstancePluginMetadata.ECSMetadata == nil {
addPluginMetadata(plugins.InstancePluginMetadata)
}
}

func addPluginMetadata(pluginmd *plugins.PluginMetadata) {
hostname, err := os.Hostname()

if err != nil {
log.Errorf("Unable to retrieve hostname from OS. %v", err)
return
}

pluginmd.ECSMetadata = &plugins.ECSMetadata{ContainerName: hostname}
pluginmd.Origin = Origin
}
32 changes: 2 additions & 30 deletions plugins/beanstalk/beanstalk.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,38 +8,10 @@

package beanstalk

import (
"encoding/json"
"io/ioutil"

"github.com/aws/aws-xray-sdk-go/internal/plugins"
log "github.com/cihub/seelog"
)
import "github.com/aws/aws-xray-sdk-go/awsplugins/beanstalk"

const Origin = "AWS::ElasticBeanstalk::Environment"

func init() {
if plugins.InstancePluginMetadata != nil && plugins.InstancePluginMetadata.BeanstalkMetadata == nil {
addPluginMetadata(plugins.InstancePluginMetadata)
}
}

func addPluginMetadata(pluginmd *plugins.PluginMetadata) {
ebConfigPath := "/var/elasticbeanstalk/xray/environment.conf"

rawConfig, err := ioutil.ReadFile(ebConfigPath)
if err != nil {
log.Errorf("Unable to read Elastic Beanstalk configuration file %s: %v", ebConfigPath, err)
return
}

config := &plugins.BeanstalkMetadata{}
err = json.Unmarshal(rawConfig, config)
if err != nil {
log.Errorf("Unable to unmarshal Elastic Beanstalk configuration file %s: %v", ebConfigPath, err)
return
}

pluginmd.BeanstalkMetadata = config
pluginmd.Origin = Origin
beanstalk.Init()
}
28 changes: 2 additions & 26 deletions plugins/ec2/ec2.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,34 +8,10 @@

package ec2

import (
"github.com/aws/aws-sdk-go/aws/ec2metadata"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-xray-sdk-go/internal/plugins"
log "github.com/cihub/seelog"
)
import "github.com/aws/aws-xray-sdk-go/awsplugins/ec2"

const Origin = "AWS::EC2::Instance"

func init() {
if plugins.InstancePluginMetadata != nil && plugins.InstancePluginMetadata.EC2Metadata == nil {
addPluginMetadata(plugins.InstancePluginMetadata)
}
}

func addPluginMetadata(pluginmd *plugins.PluginMetadata) {
session, e := session.NewSession()
if e != nil {
log.Errorf("Unable to create a new ec2 session: %v", e)
return
}
client := ec2metadata.New(session)
doc, err := client.GetInstanceIdentityDocument()
if err != nil {
log.Errorf("Unable to read EC2 instance metadata: %v", err)
return
}

pluginmd.EC2Metadata = &plugins.EC2Metadata{InstanceID: doc.InstanceID, AvailabilityZone: doc.AvailabilityZone}
pluginmd.Origin = Origin
ec2.Init()
}
23 changes: 2 additions & 21 deletions plugins/ecs/ecs.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,29 +8,10 @@

package ecs

import (
"os"

"github.com/aws/aws-xray-sdk-go/internal/plugins"
log "github.com/cihub/seelog"
)
import "github.com/aws/aws-xray-sdk-go/awsplugins/ecs"

const Origin = "AWS::ECS::Container"

func init() {
if plugins.InstancePluginMetadata != nil && plugins.InstancePluginMetadata.ECSMetadata == nil {
addPluginMetadata(plugins.InstancePluginMetadata)
}
}

func addPluginMetadata(pluginmd *plugins.PluginMetadata) {
hostname, err := os.Hostname()

if err != nil {
log.Errorf("Unable to retrieve hostname from OS. %v", err)
return
}

pluginmd.ECSMetadata = &plugins.ECSMetadata{ContainerName: hostname}
pluginmd.Origin = Origin
ecs.Init()
}

0 comments on commit 0aa94d4

Please sign in to comment.