func (client Client) CaptureMessage(message ...string) (string, error) {
	ev := Event{Message: strings.Join(message, " ")}
	sentryErr := client.Capture(&ev)
	if sentryErr != nil {
		return "", sentryErr
	}
	return ev.EventId, nil
}
CaptureMessage sends a message to the Sentry server.
It returns the Sentry event ID or an empty string and any error that occurred.
package raven
import (
	"bytes"
	"compress/zlib"
	"crypto/rand"
	"encoding/base64"
	"encoding/hex"
	"encoding/json"
	"errors"
	"fmt"
	"net"
	"net/http"
	"net/url"
	"path"
	"runtime"
	"strconv"
	"strings"
	"time"
)
type Client struct {
	URL        *url.URL
	PublicKey  string
	SecretKey  string
	Project    string
	httpClient *http.Client
}
type Frame struct {
	Filename   string `json:"filename"`
	LineNumber int    `json:"lineno"`
	FilePath   string `json:"abs_path"`
	Function   string `json:"function"`
	Module     string `json:"module"`
}
type Stacktrace struct {
	Frames []Frame `json:"frames"`
}
func generateStacktrace() Stacktrace {
	var stacktrace Stacktrace
	maxDepth := 10
	for depth := 1; depth < maxDepth; depth++ {
		pc, filePath, line, ok := runtime.Caller(depth)
		if !ok {
			break
		}
		f := runtime.FuncForPC(pc)
		if strings.Contains(f.Name(), "runtime") {
			break
		}
		if strings.Contains(f.Name(), "raven.Client") {
			continue
		}
		functionName := f.Name()
		var moduleName string
		if strings.Contains(f.Name(), "(") {
			components := strings.SplitN(f.Name(), ".(", 2)
			functionName = "(" + components[1]
			moduleName = components[0]
		}
		fileName := path.Base(filePath)
		frame := Frame{Filename: fileName, LineNumber: line, FilePath: filePath,
			Function: functionName, Module: moduleName}
		stacktrace.Frames = append(stacktrace.Frames, frame)
	}
	return stacktrace
}
type Event struct {
	EventId    string     `json:"event_id"`
	Project    string     `json:"project"`
	Message    string     `json:"message"`
	Timestamp  string     `json:"timestamp"`
	Level      string     `json:"level"`
	Logger     string     `json:"logger"`
	Culprit    string     `json:"culprit"`
	Stacktrace Stacktrace `json:"stacktrace"`
}
type sentryResponse struct {
	ResultId string `json:"result_id"`
}
const xSentryAuthTemplate = "Sentry sentry_version=2.0, sentry_client=raven-go/0.1, sentry_timestamp=%v, sentry_key=%v"
const iso8601 = "2006-01-02T15:04:05"
const defaultTimeout = 3 * time.Second
func NewClient(dsn string) (client *Client, err error) {
	u, err := url.Parse(dsn)
	if err != nil {
		return nil, err
	}
	basePath := path.Dir(u.Path)
	project := path.Base(u.Path)
	if u.User == nil {
		return nil, fmt.Errorf("the DSN must contain a public and secret key")
	}
	publicKey := u.User.Username()
	secretKey, keyIsSet := u.User.Password()
	if !keyIsSet {
		return nil, fmt.Errorf("the DSN must contain a secret key")
	}
	u.Path = basePath
	check := func(req *http.Request, via []*http.Request) error {
		fmt.Printf("%+v", req)
		return nil
	}
	httpConnectTimeout := defaultTimeout
	httpReadWriteTimeout := defaultTimeout
	if st := u.Query().Get("timeout"); st != "" {
		if timeout, err := strconv.Atoi(st); err == nil {
			httpConnectTimeout = time.Duration(timeout) * time.Second
			httpReadWriteTimeout = time.Duration(timeout) * time.Second
		} else {
			return nil, fmt.Errorf("Timeout should have an Integer argument")
		}
	}
	transport := &transport{
		httpTransport: &http.Transport{
			Dial:  timeoutDialer(httpConnectTimeout),
			Proxy: http.ProxyFromEnvironment,
		}, timeout: httpReadWriteTimeout}
	httpClient := &http.Client{
		Transport:     transport,
		CheckRedirect: check,
	}
	return &Client{URL: u, PublicKey: publicKey, SecretKey: secretKey, httpClient: httpClient, Project: project}, nil
}