Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
N
nexpie-grafana-theme
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Registry
Registry
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Kornkitt Poolsup
nexpie-grafana-theme
Commits
8f90c611
Commit
8f90c611
authored
Mar 29, 2017
by
Torkel Ödegaard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
mysql: progress on mysql data source
parent
1ecdf349
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
220 additions
and
9 deletions
+220
-9
pkg/api/frontendsettings.go
+1
-0
pkg/api/metrics.go
+16
-4
pkg/cmd/grafana-server/main.go
+1
-0
pkg/tsdb/mysql/mysql.go
+160
-0
public/app/plugins/app/testdata/datasource/datasource.ts
+5
-1
public/app/plugins/datasource/mysql/datasource.ts
+6
-4
public/app/plugins/datasource/mysql/module.ts
+4
-0
public/app/plugins/datasource/mysql/partials/config.html
+27
-0
No files found.
pkg/api/frontendsettings.go
View file @
8f90c611
...
...
@@ -42,6 +42,7 @@ func getFrontendSettingsMap(c *middleware.Context) (map[string]interface{}, erro
}
var
dsMap
=
map
[
string
]
interface
{}{
"id"
:
ds
.
Id
,
"type"
:
ds
.
Type
,
"name"
:
ds
.
Name
,
"url"
:
url
,
...
...
pkg/api/metrics.go
View file @
8f90c611
...
...
@@ -6,6 +6,7 @@ import (
"net/http"
"github.com/grafana/grafana/pkg/api/dtos"
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/metrics"
"github.com/grafana/grafana/pkg/middleware"
"github.com/grafana/grafana/pkg/models"
...
...
@@ -18,6 +19,20 @@ import (
func
QueryMetrics
(
c
*
middleware
.
Context
,
reqDto
dtos
.
MetricRequest
)
Response
{
timeRange
:=
tsdb
.
NewTimeRange
(
reqDto
.
From
,
reqDto
.
To
)
if
len
(
reqDto
.
Queries
)
==
0
{
return
ApiError
(
400
,
"No queries found in query"
,
nil
)
}
dsId
,
err
:=
reqDto
.
Queries
[
0
]
.
Get
(
"datasourceId"
)
.
Int64
()
if
err
!=
nil
{
return
ApiError
(
400
,
"Query missing datasourceId"
,
nil
)
}
dsQuery
:=
models
.
GetDataSourceByIdQuery
{
Id
:
dsId
}
if
err
:=
bus
.
Dispatch
(
&
dsQuery
);
err
!=
nil
{
return
ApiError
(
500
,
"failed to fetch data source"
,
err
)
}
request
:=
&
tsdb
.
Request
{
TimeRange
:
timeRange
}
for
_
,
query
:=
range
reqDto
.
Queries
{
...
...
@@ -26,10 +41,7 @@ func QueryMetrics(c *middleware.Context, reqDto dtos.MetricRequest) Response {
MaxDataPoints
:
query
.
Get
(
"maxDataPoints"
)
.
MustInt64
(
100
),
IntervalMs
:
query
.
Get
(
"intervalMs"
)
.
MustInt64
(
1000
),
Model
:
query
,
DataSource
:
&
models
.
DataSource
{
Name
:
"Grafana TestDataDB"
,
Type
:
"grafana-testdata-datasource"
,
},
DataSource
:
dsQuery
.
Result
,
})
}
...
...
pkg/cmd/grafana-server/main.go
View file @
8f90c611
...
...
@@ -22,6 +22,7 @@ import (
_
"github.com/grafana/grafana/pkg/tsdb/graphite"
_
"github.com/grafana/grafana/pkg/tsdb/influxdb"
_
"github.com/grafana/grafana/pkg/tsdb/mqe"
_
"github.com/grafana/grafana/pkg/tsdb/mysql"
_
"github.com/grafana/grafana/pkg/tsdb/opentsdb"
_
"github.com/grafana/grafana/pkg/tsdb/prometheus"
_
"github.com/grafana/grafana/pkg/tsdb/testdata"
...
...
pkg/tsdb/mysql/mysql.go
0 → 100644
View file @
8f90c611
package
mysql
import
(
"context"
"fmt"
"strings"
"sync"
"github.com/go-xorm/core"
"github.com/go-xorm/xorm"
"github.com/grafana/grafana/pkg/log"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/tsdb"
)
type
MysqlExecutor
struct
{
*
models
.
DataSource
engine
*
xorm
.
Engine
log
log
.
Logger
}
type
engineCacheType
struct
{
cache
map
[
int64
]
*
xorm
.
Engine
versions
map
[
int64
]
int
sync
.
Mutex
}
var
engineCache
=
engineCacheType
{
cache
:
make
(
map
[
int64
]
*
xorm
.
Engine
),
versions
:
make
(
map
[
int64
]
int
),
}
func
NewMysqlExecutor
(
datasource
*
models
.
DataSource
)
(
tsdb
.
Executor
,
error
)
{
engine
,
err
:=
getEngineFor
(
datasource
)
if
err
!=
nil
{
return
nil
,
err
}
return
&
MysqlExecutor
{
log
:
log
.
New
(
"tsdb.mysql"
),
engine
:
engine
,
},
nil
}
func
getEngineFor
(
ds
*
models
.
DataSource
)
(
*
xorm
.
Engine
,
error
)
{
engineCache
.
Lock
()
defer
engineCache
.
Unlock
()
if
engine
,
present
:=
engineCache
.
cache
[
ds
.
Id
];
present
{
if
version
,
_
:=
engineCache
.
versions
[
ds
.
Id
];
version
==
ds
.
Version
{
return
engine
,
nil
}
}
cnnstr
:=
fmt
.
Sprintf
(
"%s:%s@%s(%s)/%s?charset=utf8mb4"
,
ds
.
User
,
ds
.
Password
,
"tcp"
,
ds
.
Url
,
ds
.
Database
)
engine
,
err
:=
xorm
.
NewEngine
(
"mysql"
,
cnnstr
)
engine
.
SetMaxConns
(
10
)
engine
.
SetMaxIdleConns
(
10
)
if
err
!=
nil
{
return
nil
,
err
}
engineCache
.
cache
[
ds
.
Id
]
=
engine
return
engine
,
nil
}
func
init
()
{
tsdb
.
RegisterExecutor
(
"graphite"
,
NewMysqlExecutor
)
}
func
(
e
*
MysqlExecutor
)
Execute
(
ctx
context
.
Context
,
queries
tsdb
.
QuerySlice
,
context
*
tsdb
.
QueryContext
)
*
tsdb
.
BatchResult
{
result
:=
&
tsdb
.
BatchResult
{}
session
:=
engine
.
NewSession
()
defer
session
.
Close
()
db
:=
session
.
DB
()
result
,
err
:=
getData
(
db
,
&
req
)
if
err
!=
nil
{
return
}
}
func
getData
(
db
*
core
.
DB
,
req
*
sqlDataRequest
)
(
interface
{},
error
)
{
queries
:=
strings
.
Split
(
req
.
Query
,
";"
)
data
:=
dataStruct
{}
data
.
Results
=
make
([]
resultsStruct
,
1
)
data
.
Results
[
0
]
.
Series
=
make
([]
seriesStruct
,
0
)
for
i
:=
range
queries
{
if
queries
[
i
]
==
""
{
continue
}
rows
,
err
:=
db
.
Query
(
queries
[
i
])
if
err
!=
nil
{
return
nil
,
err
}
defer
rows
.
Close
()
name
:=
fmt
.
Sprintf
(
"table_%d"
,
i
+
1
)
series
,
err
:=
arrangeResult
(
rows
,
name
)
if
err
!=
nil
{
return
nil
,
err
}
data
.
Results
[
0
]
.
Series
=
append
(
data
.
Results
[
0
]
.
Series
,
series
.
(
seriesStruct
))
}
return
data
,
nil
}
func
arrangeResult
(
rows
*
core
.
Rows
,
name
string
)
(
interface
{},
error
)
{
columnNames
,
err
:=
rows
.
Columns
()
series
:=
seriesStruct
{}
series
.
Columns
=
columnNames
series
.
Name
=
name
for
rows
.
Next
()
{
columnValues
:=
make
([]
interface
{},
len
(
columnNames
))
err
=
rows
.
ScanSlice
(
&
columnValues
)
if
err
!=
nil
{
return
nil
,
err
}
// bytes -> string
for
i
:=
range
columnValues
{
switch
columnValues
[
i
]
.
(
type
)
{
case
[]
byte
:
columnValues
[
i
]
=
fmt
.
Sprintf
(
"%s"
,
columnValues
[
i
])
}
}
series
.
Values
=
append
(
series
.
Values
,
columnValues
)
}
return
series
,
err
}
type
sqlDataRequest
struct
{
Query
string
`json:"query"`
Body
[]
byte
`json:"-"`
}
type
seriesStruct
struct
{
Columns
[]
string
`json:"columns"`
Name
string
`json:"name"`
Values
[][]
interface
{}
`json:"values"`
}
type
resultsStruct
struct
{
Series
[]
seriesStruct
`json:"series"`
}
type
dataStruct
struct
{
Results
[]
resultsStruct
`json:"results"`
}
public/app/plugins/app/testdata/datasource/datasource.ts
View file @
8f90c611
...
...
@@ -4,9 +4,12 @@ import _ from 'lodash';
import
angular
from
'angular'
;
class
TestDataDatasource
{
id
:
any
;
/** @ngInject */
constructor
(
private
backendSrv
,
private
$q
)
{}
constructor
(
instanceSettings
,
private
backendSrv
,
private
$q
)
{
this
.
id
=
instanceSettings
.
id
;
}
query
(
options
)
{
var
queries
=
_
.
filter
(
options
.
targets
,
item
=>
{
...
...
@@ -19,6 +22,7 @@ class TestDataDatasource {
maxDataPoints
:
options
.
maxDataPoints
,
stringInput
:
item
.
stringInput
,
jsonInput
:
angular
.
fromJson
(
item
.
jsonInput
),
datasourceId
:
this
.
id
,
};
});
...
...
public/app/plugins/datasource/mysql/datasource.ts
View file @
8f90c611
...
...
@@ -3,23 +3,25 @@
import
_
from
'lodash'
;
export
class
MysqlDatasource
{
id
:
any
;
name
:
any
;
/** @ngInject */
constructor
(
private
instanceSettings
,
private
backendSrv
)
{
constructor
(
instanceSettings
,
private
backendSrv
)
{
this
.
name
=
instanceSettings
.
name
;
this
.
id
=
instanceSettings
.
id
;
}
query
(
options
)
{
console
.
log
(
'test'
);
console
.
log
(
this
.
instanceSettings
);
return
this
.
backendSrv
.
post
(
'/api/tsdb/query'
,
{
from
:
options
.
range
.
from
.
valueOf
().
toString
(),
to
:
options
.
range
.
to
.
valueOf
().
toString
(),
queries
:
[
{
"refId"
:
"A"
,
"scenarioId"
:
"random_walk"
,
"intervalMs"
:
options
.
intervalMs
,
"maxDataPoints"
:
options
.
maxDataPoints
,
"datasourceId"
:
this
.
id
,
}
]
}).
then
(
res
=>
{
...
...
public/app/plugins/datasource/mysql/module.ts
View file @
8f90c611
...
...
@@ -8,6 +8,10 @@ class MysqlQueryCtrl extends QueryCtrl {
static
templateUrl
=
'partials/query.editor.html'
;
}
class
InfluxConfigCtrl
{
static
templateUrl
=
'partials/config.html'
;
}
export
{
MysqlDatasource
,
MysqlDatasource
as
Datasource
,
...
...
public/app/plugins/datasource/mysql/partials/config.html
0 → 100644
View file @
8f90c611
<h3
class=
"page-heading"
>
MySQL Connection
</h3>
<div
class=
"gf-form-group"
>
<div
class=
"gf-form max-width-30"
>
<span
class=
"gf-form-label width-7"
>
Host
</span>
<input
type=
"text"
class=
"gf-form-input"
ng-model=
'ctrl.current.url'
placeholder=
""
required
></input>
</div>
<div
class=
"gf-form max-width-30"
>
<span
class=
"gf-form-label width-7"
>
Database
</span>
<input
type=
"text"
class=
"gf-form-input"
ng-model=
'ctrl.current.database'
placeholder=
""
required
></input>
</div>
<div
class=
"gf-form-inline"
>
<div
class=
"gf-form max-width-15"
>
<span
class=
"gf-form-label width-7"
>
User
</span>
<input
type=
"text"
class=
"gf-form-input"
ng-model=
'ctrl.current.user'
placeholder=
""
></input>
</div>
<div
class=
"gf-form max-width-15"
>
<span
class=
"gf-form-label width-7"
>
Password
</span>
<input
type=
"password"
class=
"gf-form-input"
ng-model=
'ctrl.current.password'
placeholder=
""
></input>
</div>
</div>
</div>
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment