Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(117)

Delta Between Two Patch Sets: state/api/client.go

Issue 58510045: debug-log: added new debug log api and command
Left Patch Set: debug-log: added new debug log api and command Created 11 years, 2 months ago
Right Patch Set: debug-log: added new debug log api and command Created 11 years, 1 month ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
LEFTRIGHT
1 // Copyright 2013 Canonical Ltd. 1 // Copyright 2013 Canonical Ltd.
2 // Licensed under the AGPLv3, see LICENCE file for details. 2 // Licensed under the AGPLv3, see LICENCE file for details.
3 3
4 package api 4 package api
5 5
6 import ( 6 import (
7 "encoding/base64" 7 "encoding/base64"
8 "encoding/json" 8 "encoding/json"
9 "fmt" 9 "fmt"
10 "io/ioutil" 10 "io/ioutil"
11 "net/http" 11 "net/http"
12 "net/url" 12 "net/url"
13 "os" 13 "os"
14 "time" 14 "time"
15 15
16 "code.google.com/p/go.net/websocket" 16 "code.google.com/p/go.net/websocket"
17 17
18 "launchpad.net/juju-core/charm" 18 "launchpad.net/juju-core/charm"
19 "launchpad.net/juju-core/constraints" 19 "launchpad.net/juju-core/constraints"
20 "launchpad.net/juju-core/instance" 20 "launchpad.net/juju-core/instance"
21 "launchpad.net/juju-core/juju/osenv"
22 "launchpad.net/juju-core/state/api/params" 21 "launchpad.net/juju-core/state/api/params"
23 "launchpad.net/juju-core/utils" 22 "launchpad.net/juju-core/utils"
24 "launchpad.net/juju-core/version" 23 "launchpad.net/juju-core/version"
25 ) 24 )
26 25
27 // Client represents the client-accessible part of the state. 26 // Client represents the client-accessible part of the state.
28 type Client struct { 27 type Client struct {
29 st *State 28 st *State
30 } 29 }
31 30
(...skipping 489 matching lines...) Expand 10 before | Expand all | Expand 10 after
521 } 520 }
522 521
523 // WatchDebugLog returns a ClientDebugLog reading the debug log message. 522 // WatchDebugLog returns a ClientDebugLog reading the debug log message.
524 // The filter allows to grep wanted lines out of the output, e.g. 523 // The filter allows to grep wanted lines out of the output, e.g.
525 // machines or units. The watching is started the given number of 524 // machines or units. The watching is started the given number of
526 // matching lines back in history. 525 // matching lines back in history.
527 func (c *Client) WatchDebugLog(lines int, filter string) (*ClientDebugLog, error ) { 526 func (c *Client) WatchDebugLog(lines int, filter string) (*ClientDebugLog, error ) {
528 cfg := c.st.websocketConfig 527 cfg := c.st.websocketConfig
529 // Prepare URL. 528 // Prepare URL.
530 attrs := url.Values{ 529 attrs := url.Values{
531 » » "juju-home": {osenv.JujuHomeDir()}, 530 » » "lines": {fmt.Sprintf("%d", lines)},
rog 2014/01/31 15:59:11 This doesn't seem quite right. Why are we sending
mue 2014/01/31 17:32:37 Sure there may be a way to change environ. But the
532 » » "lines": {fmt.Sprintf("%d", lines)}, 531 » » "filter": {filter},
533 » » "filter": {filter},
534 } 532 }
535 cfg.Location = &url.URL{ 533 cfg.Location = &url.URL{
536 Scheme: "wss", 534 Scheme: "wss",
537 Host: c.st.serverHostPort, 535 Host: c.st.serverHostPort,
538 Path: "/log", 536 Path: "/log",
539 RawQuery: attrs.Encode(), 537 RawQuery: attrs.Encode(),
540 } 538 }
541 cfg.Header = make(http.Header) 539 cfg.Header = make(http.Header)
542 setBasicAuth(cfg.Header, c.st.tag, c.st.password) 540 setBasicAuth(cfg.Header, c.st.tag, c.st.password)
543 541
544 wsConn, err := websocket.DialConfig(&cfg) 542 wsConn, err := websocket.DialConfig(&cfg)
545 if err != nil { 543 if err != nil {
546 return nil, err 544 return nil, err
547 } 545 }
548 return &ClientDebugLog{wsConn}, nil 546 return &ClientDebugLog{wsConn}, nil
549 } 547 }
550 548
551 // ClientDebugLog represents a stream of debug log messages. 549 // ClientDebugLog represents a stream of debug log messages.
552 type ClientDebugLog struct { 550 type ClientDebugLog struct {
553 wsConn *websocket.Conn 551 wsConn *websocket.Conn
554 } 552 }
555 553
556 // Close closes the log. 554 // Close closes the log.
557 func (c *ClientDebugLog) Close() error { 555 func (c *ClientDebugLog) Close() error {
558 return c.wsConn.Close() 556 return c.wsConn.Close()
559 } 557 }
560 558
561 // SetFilter sets the entity tags that apply to the filter. 559 // SetFilter sets the filter regular expression. This
dimitern 2014/01/31 17:02:29 s/the entity tags that apply to the filter/the fil
mue 2014/01/31 17:32:37 Will change.
mue 2014/02/02 20:11:54 Done.
562 // This setting will not take place immediately - messages 560 // setting will not take place immediately - messages
563 // already in the pipeline will still be received. 561 // already in the pipeline will still be received.
564 func (c *ClientDebugLog) SetFilter(filter string) error { 562 func (c *ClientDebugLog) SetFilter(filter string) error {
565 » req := params.EntityLogRequest{Filter: filter} 563 » req := params.DebugLogRequest{Filter: filter}
566 if err := websocket.JSON.Send(c.wsConn, &req); err != nil { 564 if err := websocket.JSON.Send(c.wsConn, &req); err != nil {
567 return err 565 return err
568 } 566 }
569 return nil 567 return nil
570 } 568 }
571 569
572 // Read implements io.Reader.Read. 570 // Read implements io.Reader.Read.
573 func (c *ClientDebugLog) Read(buf []byte) (int, error) { 571 func (c *ClientDebugLog) Read(buf []byte) (int, error) {
574 return c.wsConn.Read(buf) 572 return c.wsConn.Read(buf)
575 } 573 }
576 574
577 // setBasicAuth sets the basic authentication of the passed header. 575 // setBasicAuth creates an Authorization header for HTTP Basic
dimitern 2014/01/31 17:02:29 // setBasicAuth creates an Authorization header fo
mue 2014/01/31 17:32:37 Please discuss with Roger. It's based on his draft
dimitern 2014/01/31 17:57:09 I'm just suggesting a more appropriate description
mue 2014/02/02 20:11:54 Done.
576 // Authentication, using the given username and password.
578 func setBasicAuth(h http.Header, username, password string) { 577 func setBasicAuth(h http.Header, username, password string) {
579 h.Set("Authorization", "Basic "+basicAuth(username, password)) 578 h.Set("Authorization", "Basic "+basicAuth(username, password))
580 } 579 }
581 580
582 // basicAuth is copied from net/http. 581 // basicAuth is copied from net/http.
583 // See 2 (end of page 4) http://www.ietf.org/rfc/rfc2617.txt 582 // See 2 (end of page 4) http://www.ietf.org/rfc/rfc2617.txt
584 // "To receive authorization, the client sends the userid and password, 583 // "To receive authorization, the client sends the userid and password,
585 // separated by a single colon (":") character, within a base64 584 // separated by a single colon (":") character, within a base64
586 // encoded string in the credentials." 585 // encoded string in the credentials."
587 // It is not meant to be urlencoded. 586 // It is not meant to be urlencoded.
588 func basicAuth(username, password string) string { 587 func basicAuth(username, password string) string {
589 auth := username + ":" + password 588 auth := username + ":" + password
590 return base64.StdEncoding.EncodeToString([]byte(auth)) 589 return base64.StdEncoding.EncodeToString([]byte(auth))
591 } 590 }
LEFTRIGHT

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b