Skip to content

Commit 41a84dd

Browse files
author
Ted Pearson
committed
move all logic out of main, write metrics support, initial work into querying previous metrics
1 parent e6c3a42 commit 41a84dd

File tree

7 files changed

+241
-48
lines changed

7 files changed

+241
-48
lines changed

go.mod

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,21 @@ go 1.19
55
require (
66
github.com/chromedp/cdproto v0.0.0-20220924210414-0e3390be1777
77
github.com/chromedp/chromedp v0.8.6
8+
github.com/influxdata/influxdb-client-go/v2 v2.11.0
89
github.com/shopspring/decimal v1.3.1
910
gopkg.in/yaml.v3 v3.0.1
1011
)
1112

1213
require (
1314
github.com/chromedp/sysutil v1.0.0 // indirect
15+
github.com/deepmap/oapi-codegen v1.8.2 // indirect
1416
github.com/gobwas/httphead v0.1.0 // indirect
1517
github.com/gobwas/pool v0.2.1 // indirect
1618
github.com/gobwas/ws v1.1.0 // indirect
19+
github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839 // indirect
1720
github.com/josharian/intern v1.0.0 // indirect
1821
github.com/mailru/easyjson v0.7.7 // indirect
22+
github.com/pkg/errors v0.9.1 // indirect
23+
golang.org/x/net v0.0.0-20210119194325-5f4716e94777 // indirect
1924
golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec // indirect
2025
)

go.sum

Lines changed: 82 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,24 +4,105 @@ github.com/chromedp/chromedp v0.8.6 h1:KobeeqR2dpfKSG1prS3Y6+FbffMmGC6xmAobRXA9Q
44
github.com/chromedp/chromedp v0.8.6/go.mod h1:nBYHoD6YSNzrr82cIeuOzhw1Jo/s2o0QQ+ifTeoCZ+c=
55
github.com/chromedp/sysutil v1.0.0 h1:+ZxhTpfpZlmchB58ih/LBHX52ky7w2VhQVKQMucy3Ic=
66
github.com/chromedp/sysutil v1.0.0/go.mod h1:kgWmDdq8fTzXYcKIBqIYvRRTnYb9aNS9moAV0xufSww=
7+
github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4=
8+
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
9+
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
10+
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
11+
github.com/deepmap/oapi-codegen v1.8.2 h1:SegyeYGcdi0jLLrpbCMoJxnUUn8GBXHsvr4rbzjuhfU=
12+
github.com/deepmap/oapi-codegen v1.8.2/go.mod h1:YLgSKSDv/bZQB7N4ws6luhozi3cEdRktEqrX88CvjIw=
13+
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
14+
github.com/getkin/kin-openapi v0.61.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4=
15+
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
16+
github.com/go-chi/chi/v5 v5.0.0/go.mod h1:BBug9lr0cqtdAhsu6R4AAdvufI0/XBzAQSsUqJpoZOs=
17+
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
18+
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
719
github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU=
820
github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM=
921
github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og=
1022
github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
1123
github.com/gobwas/ws v1.1.0 h1:7RFti/xnNkMJnrK7D1yQ/iCIB5OrrY/54/H930kIbHA=
1224
github.com/gobwas/ws v1.1.0/go.mod h1:nzvNcVha5eUziGrbxFCo6qFIojQHjJV5cLYIbezhfL0=
25+
github.com/golangci/lint-1 v0.0.0-20181222135242-d2cdd8c08219/go.mod h1:/X8TswGSh1pIozq4ZwCfxS0WA5JGXguxk94ar/4c87Y=
26+
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
27+
github.com/influxdata/influxdb-client-go/v2 v2.11.0 h1:BrHYv38rWkAnp22gIaHFp5LpOCazOqRMRvVE1yW3ym8=
28+
github.com/influxdata/influxdb-client-go/v2 v2.11.0/go.mod h1:YteV91FiQxRdccyJ2cHvj2f/5sq4y4Njqu1fQzsQCOU=
29+
github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839 h1:W9WBk7wlPfJLvMCdtV4zPulc4uCPrlywQOmbFOhgQNU=
30+
github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo=
1331
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
1432
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
33+
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
34+
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
35+
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
36+
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
37+
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
38+
github.com/labstack/echo/v4 v4.2.1/go.mod h1:AA49e0DZ8kk5jTOOCKNuPR6oTnBS0dYiM4FW1e6jwpg=
39+
github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k=
1540
github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80 h1:6Yzfa6GP0rIo/kULo2bwGEkFvCePZ3qHDDTC3/J9Swo=
41+
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
42+
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
1643
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
1744
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
45+
github.com/matryer/moq v0.0.0-20190312154309-6cfb0558e1bd/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ=
46+
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
47+
github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
48+
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
49+
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
50+
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
51+
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
1852
github.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde h1:x0TT0RDC7UhAVbbWWBzr41ElhJx5tXPWkIHA2HWPRuw=
53+
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
54+
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
55+
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
56+
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
57+
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
1958
github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8=
2059
github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
60+
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
61+
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
62+
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
63+
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
64+
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
65+
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
66+
github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
67+
github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
68+
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
69+
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
70+
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
71+
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
72+
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
73+
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
74+
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
75+
golang.org/x/net v0.0.0-20210119194325-5f4716e94777 h1:003p0dJM77cxMSyCPFphvZf/Y5/NXf5fzg6ufd1/Oew=
76+
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
77+
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
78+
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
79+
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
80+
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
81+
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
82+
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
83+
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
84+
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
85+
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
86+
golang.org/x/sys v0.0.0-20200826173525-f9321e4c35a6/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
87+
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
2188
golang.org/x/sys v0.0.0-20201207223542-d4d67f95c62d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
89+
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
2290
golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec h1:BkDtF2Ih9xZ7le9ndzTA7KJow28VbQW3odyk/8drmuI=
2391
golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
24-
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
92+
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
93+
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
94+
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
95+
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
96+
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
97+
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
98+
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
99+
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
100+
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
101+
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
25102
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
103+
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
104+
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
105+
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
106+
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
26107
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
27108
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

internal/app/browser.go

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,20 +10,13 @@ import (
1010
"github.com/chromedp/chromedp"
1111
)
1212

13-
type Config struct {
14-
Username string
15-
Password string
16-
LoginUrl string
17-
DownloadDir string
18-
}
19-
2013
func DownloadCsv(config *Config, startDate string, endDate string) (string, error) {
2114
allocatorFlags := append(chromedp.DefaultExecAllocatorOptions[:], chromedp.Flag("headless", false))
2215
ctx, cancel := chromedp.NewExecAllocator(context.Background(), allocatorFlags...)
2316
defer cancel()
2417
ctx, cancel = chromedp.NewContext(ctx, chromedp.WithLogf(log.Printf))
2518
defer cancel()
26-
ctx, cancel = context.WithTimeout(ctx, 15*time.Second)
19+
ctx, cancel = context.WithTimeout(ctx, 30*time.Second)
2720
defer cancel()
2821

2922
done := make(chan string, 1)

internal/app/main.go

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package app
2+
3+
import (
4+
"fmt"
5+
"log"
6+
"os"
7+
8+
"gopkg.in/yaml.v3"
9+
)
10+
11+
var (
12+
startDate = "09/29/2022"
13+
endDate = "09/30/2022"
14+
)
15+
16+
type InfluxDB struct {
17+
Host string
18+
User string
19+
Password string
20+
Database string
21+
}
22+
23+
type Config struct {
24+
Username string
25+
Password string
26+
LoginUrl string
27+
DownloadDir string
28+
InfluxDB InfluxDB
29+
}
30+
31+
func Main() {
32+
33+
// read config
34+
file, err := os.ReadFile("config.yaml")
35+
if err != nil {
36+
log.Fatal(err)
37+
}
38+
config := &Config{}
39+
err = yaml.Unmarshal(file, config)
40+
if err != nil {
41+
log.Fatal(err)
42+
}
43+
44+
path, err := DownloadCsv(config, startDate, endDate)
45+
if err != nil {
46+
log.Fatal(err)
47+
}
48+
fmt.Printf("file downloaded: %s", path)
49+
// parse csv!
50+
records, err := ParseCsv(path)
51+
if err != nil {
52+
log.Fatal(err)
53+
}
54+
fmt.Printf("%+v", records)
55+
WriteMetrics(records, config.InfluxDB)
56+
}

internal/app/metrics.go

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
package app
2+
3+
import (
4+
"context"
5+
"encoding/json"
6+
"log"
7+
"net/http"
8+
"net/url"
9+
"strings"
10+
"time"
11+
12+
"github.com/influxdata/influxdb-client-go/v2"
13+
"github.com/influxdata/influxdb-client-go/v2/api/write"
14+
)
15+
16+
//type Metric struct {
17+
// Name string `json:"__name__"`
18+
// Db string
19+
//}
20+
21+
type MetricLine struct {
22+
//Metric Metric
23+
//Values []float64
24+
Timestamps []int64
25+
}
26+
27+
func WriteMetrics(records []*ElectricUsage, config InfluxDB) {
28+
client := influxdb2.NewClient(config.Host, config.User+":"+config.Password)
29+
writeApi := client.WriteAPIBlocking("", config.Database)
30+
points := make([]*write.Point, 0, 15*2*len(records))
31+
for _, record := range records {
32+
divisor := record.EndTime.Sub(record.StartTime).Minutes()
33+
for t := record.StartTime; record.EndTime.After(t); t = t.Add(time.Minute) {
34+
watts := influxdb2.NewPointWithMeasurement("electric").
35+
SetTime(t).
36+
AddField("usage", float64(record.WattHours)/divisor)
37+
cost := influxdb2.NewPointWithMeasurement("electric").
38+
SetTime(t).
39+
AddField("cost", float64(record.CostInCents)/divisor)
40+
points = append(points, watts, cost)
41+
}
42+
}
43+
44+
err := writeApi.WritePoint(context.Background(), points...)
45+
if err != nil {
46+
log.Fatal(err)
47+
}
48+
// query VM for metrics that already exist in the range we're trying to insert?
49+
// if that's too much work, then just maintain last-inserted-time and don't insert newer
50+
log.Println(points)
51+
}
52+
53+
// the goal here is to not double write any metrics
54+
// therefore, we should simply filter inserted points by any points that
55+
// already exist.
56+
// the algorithm for that is to run this query first, making a map[time]struct{}
57+
// and discarding any point in WriteMetrics that exists in the map.
58+
59+
func QueryPreviousMetrics(startTime time.Time, endTime time.Time, config InfluxDB) map[int64]struct{} {
60+
client := &http.Client{}
61+
v := url.Values{
62+
"match[]": {"sensor_temperature"},
63+
"start": {startTime.Format("2006-01-02T15:04:05+07:00")},
64+
"end": {endTime.Format("2006-01-02T15:04:05+07:00")},
65+
}
66+
req, err := http.NewRequest("POST", config.Host+"/api/v1/export", strings.NewReader(v.Encode()))
67+
if err != nil {
68+
log.Fatal(err)
69+
}
70+
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
71+
req.SetBasicAuth(config.User, config.Password)
72+
resp, err := client.Do(req)
73+
if err != nil {
74+
log.Fatal(err)
75+
}
76+
defer func() {
77+
err := resp.Body.Close()
78+
if err != nil {
79+
log.Fatal(err)
80+
}
81+
}()
82+
existing := make(map[int64]struct{})
83+
decoder := json.NewDecoder(resp.Body)
84+
for decoder.More() {
85+
var line MetricLine
86+
if err := decoder.Decode(&line); err != nil {
87+
log.Printf("Bad line: %w\n", err)
88+
}
89+
for _, ts := range line.Timestamps {
90+
existing[ts] = struct{}{}
91+
}
92+
}
93+
return existing
94+
}

internal/app/parser.go

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,7 @@ type ElectricUsage struct {
1818
CostInCents int64
1919
}
2020

21-
type ElectricRecords struct {
22-
ElectricUsage []*ElectricUsage
23-
}
24-
25-
func ParseCsv(file string) (*ElectricRecords, error) {
21+
func ParseCsv(file string) ([]*ElectricUsage, error) {
2622
dateRegex, err := regexp.Compile(`(\d{4}-\d\d-\d\d \d\d:\d\d) to (\d{4}-\d\d-\d\d \d\d:\d\d)`)
2723
if err != nil {
2824
log.Fatal(err)
@@ -49,7 +45,7 @@ func ParseCsv(file string) (*ElectricRecords, error) {
4945
records = append(records, usage)
5046
}
5147
}
52-
return &ElectricRecords{records}, nil
48+
return records, nil
5349
}
5450

5551
func parseRecord(row []string, dates []string) *ElectricUsage {

main.go

Lines changed: 1 addition & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,9 @@
11
package main
22

33
import (
4-
"fmt"
5-
"log"
6-
"os"
7-
8-
"gopkg.in/yaml.v3"
9-
104
"electric-usage-downloader/internal/app"
115
)
126

13-
var (
14-
startDate = "09/29/2022"
15-
endDate = "09/30/2022"
16-
)
17-
187
func main() {
19-
// read config
20-
file, err := os.ReadFile("config.yaml")
21-
if err != nil {
22-
log.Fatal(err)
23-
}
24-
config := &app.Config{}
25-
err = yaml.Unmarshal(file, config)
26-
if err != nil {
27-
log.Fatal(err)
28-
}
29-
30-
path, err := app.DownloadCsv(config, startDate, endDate)
31-
if err != nil {
32-
log.Fatal(err)
33-
}
34-
fmt.Printf("file downloaded: %s", path)
35-
// parse csv!
36-
records, err := app.ParseCsv(path)
37-
if err != nil {
38-
log.Fatal(err)
39-
}
40-
fmt.Printf("%+v", records)
8+
app.Main()
419
}

0 commit comments

Comments
 (0)