logging.info for more important loggings and logging.debug for less important loggings that user might not care about

This commit is contained in:
Huy Pham 2020-01-29 16:08:36 -08:00
parent 6aa7d2175d
commit 6c89ba1abb
14 changed files with 132 additions and 62 deletions

View file

@ -167,7 +167,6 @@ class CoreClient:
return
if event.HasField("link_event"):
logging.info("link event: %s", event)
self.handle_link_event(event.link_event)
elif event.HasField("session_event"):
logging.info("session event: %s", event)
@ -185,7 +184,7 @@ class CoreClient:
else:
dialog.set_pause()
else:
logging.warning("unknown session event: %s", session_event)
logging.warning("Unknown session event: %s", session_event)
elif event.HasField("node_event"):
self.handle_node_event(event.node_event)
elif event.HasField("config_event"):
@ -193,9 +192,10 @@ class CoreClient:
elif event.HasField("exception_event"):
self.handle_exception_event(event)
else:
logging.info("unhandled event: %s", event)
logging.info("Unhandled event: %s", event)
def handle_link_event(self, event: core_pb2.LinkEvent):
logging.debug("Link event: %s", event)
node_one_id = event.link.node_one_id
node_two_id = event.link.node_two_id
canvas_node_one = self.canvas_nodes[node_one_id]
@ -209,6 +209,7 @@ class CoreClient:
logging.warning("unknown link event: %s", event.message_type)
def handle_node_event(self, event: core_pb2.NodeEvent):
logging.debug("Node event: %s", event)
if event.source == GUI_SOURCE:
return
node_id = event.node.id
@ -234,14 +235,15 @@ class CoreClient:
self.session_id,
)
return
logging.info("handling throughputs event: %s", event)
logging.debug("handling throughputs event: %s", event)
self.app.canvas.set_throughputs(event)
def handle_exception_event(self, event: core_pb2.ExceptionEvent):
logging.info("exception event: %s", event)
logging.info("Exception event: %s", event)
self.app.statusbar.core_alarms.append(event)
def join_session(self, session_id: int, query_location: bool = True):
logging.info("Join session(%s)", session_id)
# update session and title
self.session_id = session_id
self.master.title(f"CORE Session({self.session_id})")
@ -303,7 +305,7 @@ class CoreClient:
for config in response.configs:
service_configs = self.service_configs.setdefault(config.node_id, {})
service_configs[config.service] = config.data
logging.info("service file configs: %s", config.files)
logging.debug("service file configs: %s", config.files)
for file_name in config.files:
file_configs = self.file_configs.setdefault(config.node_id, {})
files = file_configs.setdefault(config.service, {})
@ -341,7 +343,7 @@ class CoreClient:
def parse_metadata(self, config: Dict[str, str]):
# canvas setting
canvas_config = config.get("canvas")
logging.info("canvas metadata: %s", canvas_config)
logging.debug("canvas metadata: %s", canvas_config)
if canvas_config:
canvas_config = json.loads(canvas_config)
@ -425,7 +427,7 @@ class CoreClient:
session_id = self.session_id
try:
response = self.client.delete_session(session_id)
logging.info("deleted session(%s) result: %s", session_id, response)
logging.info("delete session(%s), Result: %s", session_id, response)
except grpc.RpcError as e:
self.app.after(0, show_grpc_error, e)
@ -435,7 +437,7 @@ class CoreClient:
"""
try:
self.client.connect()
logging.debug("Client connect to daemon")
# get service information
response = self.client.get_services()
for service in response.services:
@ -453,7 +455,6 @@ class CoreClient:
# if there are no sessions, create a new session, else join a session
response = self.client.get_sessions()
logging.info("current sessions: %s", response)
sessions = response.sessions
if len(sessions) == 0:
self.create_new_session()
@ -511,8 +512,8 @@ class CoreClient:
asymmetric_links,
config_service_configs,
)
logging.debug(
"start session(%s), result: %s", self.session_id, response.result
logging.info(
"Start session(%s), Result: %s", self.session_id, response.result
)
if response.result:
@ -527,7 +528,7 @@ class CoreClient:
response = core_pb2.StopSessionResponse(result=False)
try:
response = self.client.stop_session(session_id)
logging.debug("stopped session(%s), result: %s", session_id, response)
logging.info("Stop session(%s), Result: %s", session_id, response)
except grpc.RpcError as e:
self.app.after(0, show_grpc_error, e)
return response
@ -561,7 +562,7 @@ class CoreClient:
metadata = {"canvas": canvas_config, "shapes": shapes}
response = self.client.set_session_metadata(self.session_id, metadata)
logging.info("set session metadata: %s", response)
logging.info("Set session metadata %s, Result: %s", metadata, response)
def launch_terminal(self, node_id: int):
try:
@ -571,7 +572,7 @@ class CoreClient:
if output in DEFAULT_TERMS:
terminal = DEFAULT_TERMS[output]
cmd = f'{terminal} "{response.terminal}" &'
logging.info("launching terminal %s", cmd)
logging.info("Launch terminal %s", cmd)
os.system(cmd)
except grpc.RpcError as e:
self.app.after(0, show_grpc_error, e)
@ -582,12 +583,10 @@ class CoreClient:
"""
try:
if self.state != core_pb2.SessionState.RUNTIME:
logging.debug(
"session state not runtime, send session data to the daemon..."
)
logging.debug("Send session data to the daemon")
self.send_data()
response = self.client.save_xml(self.session_id, file_path)
logging.info("saved xml(%s): %s", file_path, response)
logging.info("Save XML file %s, Result: %s", file_path, response)
except grpc.RpcError as e:
self.app.after(0, show_grpc_error, e)
@ -597,7 +596,7 @@ class CoreClient:
"""
try:
response = self.client.open_xml(file_path)
logging.debug("open xml: %s", response)
logging.info("Open XML file %s, Response: %s", file_path, response)
self.join_session(response.session_id)
except grpc.RpcError as e:
self.app.after(0, show_grpc_error, e)
@ -606,7 +605,9 @@ class CoreClient:
self, node_id: int, service_name: str
) -> core_pb2.NodeServiceData:
response = self.client.get_node_service(self.session_id, node_id, service_name)
logging.debug("get node service %s", response)
logging.debug(
"Get node(%s) %s service, Response: %s", node_id, service_name, response
)
return response.service
def set_node_service(
@ -620,9 +621,16 @@ class CoreClient:
response = self.client.set_node_service(
self.session_id, node_id, service_name, startups, validations, shutdowns
)
logging.debug("set node service %s", response)
logging.info(
"Set %s service for node(%s), Startup: %s, Validation: %s, Shutdown: %s, Result: %s",
service_name,
node_id,
startups,
validations,
shutdowns,
response,
)
response = self.client.get_node_service(self.session_id, node_id, service_name)
logging.debug("get node service : %s", response)
return response.service
def get_node_service_file(
@ -631,7 +639,13 @@ class CoreClient:
response = self.client.get_node_service_file(
self.session_id, node_id, service_name, file_name
)
logging.debug("get service file %s", response)
logging.debug(
"Get service file for node(%s), Service: %s, File: %s, Result: %s",
node_id,
service_name,
file_name,
response,
)
return response.data
def set_node_service_file(
@ -640,7 +654,14 @@ class CoreClient:
response = self.client.set_node_service_file(
self.session_id, node_id, service_name, file_name, data
)
logging.debug("set node service file %s", response)
logging.info(
"Set node(%s) service file, Service: %s, File: %s, Data: %s, Result: %s",
node_id,
service_name,
file_name,
data,
response,
)
def create_nodes_and_links(self):
"""
@ -656,7 +677,7 @@ class CoreClient:
self.client.set_session_state(self.session_id, core_pb2.SessionState.DEFINITION)
for node_proto in node_protos:
response = self.client.add_node(self.session_id, node_proto)
logging.debug("create node: %s", response)
logging.debug("Create node: %s", response)
for link_proto in link_protos:
response = self.client.add_link(
self.session_id,
@ -666,7 +687,7 @@ class CoreClient:
link_proto.interface_two,
link_proto.options,
)
logging.debug("create link: %s", response)
logging.debug("Create link: %s", response)
def send_data(self):
"""
@ -733,7 +754,7 @@ class CoreClient:
return i
def create_node(
self, x: int, y: int, node_type: core_pb2.NodeType, model: str
self, x: float, y: float, node_type: core_pb2.NodeType, model: str
) -> core_pb2.Node:
"""
Add node, with information filled in, to grpc manager
@ -765,12 +786,12 @@ class CoreClient:
if NodeUtils.is_custom(model):
services = NodeUtils.get_custom_node_services(self.app.guiconfig, model)
node.services[:] = services
logging.debug(
"adding node to core session: %s, coords: (%s, %s), name: %s",
logging.info(
"Add node(%s) to session(%s), coordinates(%s, %s)",
node.name,
self.session_id,
x,
y,
node.name,
)
return node
@ -860,6 +881,7 @@ class CoreClient:
)
edge.set_link(link)
self.links[edge.token] = edge
logging.info("Add link between %s and %s", src_node.name, dst_node.name)
def get_wlan_configs_proto(self) -> List[core_pb2.WlanConfig]:
configs = []
@ -940,6 +962,11 @@ class CoreClient:
if not config:
response = self.client.get_wlan_config(self.session_id, node_id)
config = response.config
logging.debug(
"Get wlan configuration from node %s, Result configuration: %s",
node_id,
config,
)
return config
def get_mobility_config(self, node_id: int) -> Dict[str, common_pb2.ConfigOption]:
@ -947,12 +974,16 @@ class CoreClient:
if not config:
response = self.client.get_mobility_config(self.session_id, node_id)
config = response.config
logging.debug(
"Get mobility config from node %s, Result configuration: %s",
node_id,
config,
)
return config
def get_emane_model_config(
self, node_id: int, model: str, interface: int = None
) -> Dict[str, common_pb2.ConfigOption]:
logging.info("getting emane model config: %s %s %s", node_id, model, interface)
config = self.emane_model_configs.get((node_id, model, interface))
if not config:
if interface is None:
@ -961,6 +992,13 @@ class CoreClient:
self.session_id, node_id, model, interface
)
config = response.config
logging.debug(
"Get emane model config: Node id: %s, EMANE model: %s, Interface: %s, Config: %s",
node_id,
model,
interface,
config,
)
return config
def set_emane_model_config(
@ -970,12 +1008,19 @@ class CoreClient:
config: Dict[str, common_pb2.ConfigOption],
interface: int = None,
):
logging.info("setting emane model config: %s %s %s", node_id, model, interface)
logging.info(
"Set emane model config: Node id: %s, EMANE Model: %s, Interface: %s, Config: %s",
node_id,
model,
interface,
config,
)
self.emane_model_configs[(node_id, model, interface)] = config
def copy_node_service(self, _from: int, _to: int):
services = self.canvas_nodes[_from].core_node.services
self.canvas_nodes[_to].core_node.services[:] = services
logging.debug("Copy node %s service to node %s", _from, _to)
def copy_node_config(self, _from: int, _to: int):
node_type = self.canvas_nodes[_from].core_node.type

View file

@ -107,6 +107,7 @@ class EmaneConfigDialog(Dialog):
def __init__(
self, master: "Application", app: "Application", canvas_node: "CanvasNode"
):
logging.debug("EMANE configuration for %s", canvas_node.core_node.name)
super().__init__(
master, app, f"{canvas_node.core_node.name} EMANE Configuration", modal=True
)

View file

@ -1,6 +1,7 @@
"""
mobility configuration
"""
import logging
from tkinter import ttk
from typing import TYPE_CHECKING
@ -20,6 +21,7 @@ class MobilityConfigDialog(Dialog):
def __init__(
self, master: "Application", app: "Application", canvas_node: "CanvasNode"
):
logging.debug("Mobility configuration for %s", canvas_node.core_node.name)
super().__init__(
master,
app,

View file

@ -52,6 +52,7 @@ class NodeConfigDialog(Dialog):
"""
create an instance of node configuration
"""
logging.debug("Node configuration for %s", canvas_node.core_node.name)
super().__init__(
master, app, f"{canvas_node.core_node.name} Configuration", modal=True
)

View file

@ -24,6 +24,7 @@ class NodeConfigServiceDialog(Dialog):
canvas_node: "CanvasNode",
services: Set[str] = None,
):
logging.debug("Service configuration for %s", canvas_node.core_node.name)
title = f"{canvas_node.core_node.name} Config Services"
super().__init__(master, app, title, modal=True)
self.app = app

View file

@ -1,6 +1,7 @@
"""
core node services
"""
import logging
import tkinter as tk
from tkinter import messagebox, ttk
from typing import TYPE_CHECKING, Any, Set
@ -24,6 +25,7 @@ class NodeServiceDialog(Dialog):
canvas_node: "CanvasNode",
services: Set[str] = None,
):
logging.debug("Node services for %s", canvas_node.core_node.name)
title = f"{canvas_node.core_node.name} Services"
super().__init__(master, app, title, modal=True)
self.app = app

View file

@ -2,6 +2,7 @@
wlan configuration
"""
import logging
from tkinter import ttk
from typing import TYPE_CHECKING
@ -21,6 +22,7 @@ class WlanConfigDialog(Dialog):
def __init__(
self, master: "Application", app: "Application", canvas_node: "CanvasNode"
):
logging.debug("Wlan Configuration for %s", canvas_node.core_node.name)
super().__init__(
master, app, f"{canvas_node.core_node.name} Wlan Configuration", modal=True
)

View file

@ -25,6 +25,7 @@ class CanvasWirelessEdge:
dst: int,
canvas: "CanvasGraph",
):
logging.debug("Draw wireless link from node %s to node %s", src, dst)
self.token = token
self.src = src
self.dst = dst
@ -167,6 +168,7 @@ class CanvasEdge:
self.check_wireless()
self.canvas.tag_raise(self.src)
self.canvas.tag_raise(self.dst)
logging.debug("Draw wired link from node %s to node %s", self.src, dst)
def is_wireless(self) -> [bool, bool]:
src_node = self.canvas.nodes[self.src]
@ -198,6 +200,7 @@ class CanvasEdge:
src_node.add_antenna()
def delete(self):
logging.debug("Delete canvas edge, id: %s", self.id)
self.canvas.delete(self.id)
if self.link:
self.canvas.delete(self.text_src)

View file

@ -216,6 +216,7 @@ class CanvasGraph(tk.Canvas):
"""
# draw existing nodes
for core_node in session.nodes:
logging.debug("Draw node %s", core_node)
# peer to peer node is not drawn on the GUI
if NodeUtils.is_ignore_node(core_node.type):
continue
@ -231,7 +232,7 @@ class CanvasGraph(tk.Canvas):
# draw existing links
for link in session.links:
logging.info("drawing link: %s", link)
logging.debug("Draw link: %s", link)
canvas_node_one = self.core.canvas_nodes[link.node_one_id]
node_one = canvas_node_one.core_node
canvas_node_two = self.core.canvas_nodes[link.node_two_id]
@ -388,7 +389,6 @@ class CanvasGraph(tk.Canvas):
# set dst node and snap edge to center
edge.complete(self.selected)
logging.debug("drawing edge token: %s", edge.token)
self.edges[edge.token] = edge
node_src = self.nodes[edge.src]
@ -508,7 +508,7 @@ class CanvasGraph(tk.Canvas):
logging.debug("click press(%s): %s", self.cursor, selected)
x_check = self.cursor[0] - self.offset[0]
y_check = self.cursor[1] - self.offset[1]
logging.debug("clock press ofset(%s, %s)", x_check, y_check)
logging.debug("click press offset(%s, %s)", x_check, y_check)
is_node = selected in self.nodes
if self.mode == GraphMode.EDGE and is_node:
x, y = self.coords(selected)
@ -545,7 +545,8 @@ class CanvasGraph(tk.Canvas):
self.select_object(node.id)
self.selected = selected
logging.info(
"selected coords: (%s, %s)",
"selected node(%s), coords: (%s, %s)",
node.core_node.name,
node.core_node.position.x,
node.core_node.position.y,
)
@ -631,7 +632,6 @@ class CanvasGraph(tk.Canvas):
self.select_box.shape_motion(x, y)
def click_context(self, event: tk.Event):
logging.info("context event: %s", self.context)
if not self.context:
selected = self.get_selected(event)
canvas_node = self.nodes.get(selected)
@ -796,14 +796,14 @@ class CanvasGraph(tk.Canvas):
self.tag_raise(component)
def update_grid(self):
logging.info("updating grid show: %s", self.show_grid.get())
logging.debug("Show grid: %s", self.show_grid.get())
if self.show_grid.get():
self.itemconfig(tags.GRIDLINE, state=tk.NORMAL)
else:
self.itemconfig(tags.GRIDLINE, state=tk.HIDDEN)
def set_wallpaper(self, filename: str):
logging.info("setting wallpaper: %s", filename)
logging.debug("Set wallpaper: %s", filename)
if filename:
img = Image.open(filename)
self.wallpaper = img
@ -835,14 +835,11 @@ class CanvasGraph(tk.Canvas):
def copy(self):
if self.selection:
logging.debug(
"store current selection to to_copy, number of nodes: %s",
len(self.selection),
)
logging.debug("Copy %s nodes", len(self.selection))
self.to_copy = self.selection.keys()
def paste(self):
logging.debug("copy")
logging.debug("Paste")
# maps original node canvas id to copy node canvas id
copy_map = {}
# the edges that will be copy over

View file

@ -1,3 +1,4 @@
import logging
import tkinter as tk
from tkinter import font
from typing import TYPE_CHECKING
@ -41,6 +42,9 @@ class CanvasNode:
self.id = self.canvas.create_image(
x, y, anchor=tk.CENTER, image=self.image, tags=tags.NODE
)
logging.debug(
"Draw canvas node for node(%s), canvas id: %s", core_node.name, self.id
)
text_font = font.Font(family="TkIconFont", size=12)
label_y = self._get_label_y()
self.text_id = self.canvas.create_text(
@ -64,9 +68,10 @@ class CanvasNode:
self.canvas.tag_bind(self.id, "<Leave>", self.on_leave)
def delete(self):
logging.debug("Delete canvas node for %s", self.core_node)
self.canvas.delete(self.id)
self.canvas.delete(self.text_id)
self.delete_antennae()
self.delete_antennas()
def add_antenna(self):
x, y = self.canvas.coords(self.id)
@ -84,14 +89,16 @@ class CanvasNode:
"""
delete one antenna
"""
logging.debug("Delete an antenna on %s", self.core_node.name)
if self.antennae:
antenna_id = self.antennae.pop()
self.canvas.delete(antenna_id)
def delete_antennae(self):
def delete_antennas(self):
"""
delete all antennas
"""
logging.debug("Remove all antennas for %s", self.core_node.name)
for antenna_id in self.antennae:
self.canvas.delete(antenna_id)
self.antennae.clear()
@ -244,6 +251,7 @@ class CanvasNode:
dialog.show()
def show_mobility_player(self):
logging.debug("Mobility player for %s", self.core_node.name)
self.canvas.context = None
mobility_player = self.app.core.mobility_players[self.core_node.id]
mobility_player.show()

View file

@ -86,6 +86,7 @@ class Shape:
outline=self.shape_data.border_color,
width=self.shape_data.border_width,
)
logging.debug("Create oval, id(%s)", self.id)
self.draw_shape_text()
elif self.shape_type == ShapeType.RECTANGLE:
self.id = self.canvas.create_rectangle(
@ -99,6 +100,7 @@ class Shape:
outline=self.shape_data.border_color,
width=self.shape_data.border_width,
)
logging.debug("Create rectangle, id(%s)", self.id)
self.draw_shape_text()
elif self.shape_type == ShapeType.TEXT:
font = self.get_font()
@ -110,6 +112,7 @@ class Shape:
fill=self.shape_data.text_color,
font=font,
)
logging.debug("Create text, id(%s)", self.id)
else:
logging.error("unknown shape type: %s", self.shape_type)
self.created = True
@ -144,6 +147,7 @@ class Shape:
def shape_complete(self, x: float, y: float):
for component in tags.ABOVE_SHAPE:
self.canvas.tag_raise(component)
logging.debug("Complete shape, id(%s)", self.id)
s = ShapeDialog(self.app, self.app, self)
s.show()
@ -163,6 +167,7 @@ class Shape:
self.canvas.move(self.text_id, x_offset, y_offset)
def delete(self):
logging.debug("Delete shape, id(%s)", self.id)
self.canvas.delete(self.id)
self.canvas.delete(self.text_id)

View file

@ -33,9 +33,11 @@ class MenuAction:
self.canvas = app.canvas
def cleanup_old_session(self, session_id):
logging.info("cleaning up old session")
self.app.core.stop_session()
response = self.app.core.stop_session()
self.app.core.delete_session(session_id)
logging.info(
"Stop session(%s) and delete it, result: %s", session_id, response.result
)
def prompt_save_running_session(self, quitapp: bool = False):
"""
@ -66,7 +68,6 @@ class MenuAction:
self.prompt_save_running_session(quitapp=True)
def file_save_as_xml(self, event: tk.Event = None):
logging.info("menuaction.py file_save_as_xml()")
init_dir = self.app.core.xml_dir
if not init_dir:
init_dir = str(XMLS_PATH)
@ -83,14 +84,12 @@ class MenuAction:
init_dir = self.app.core.xml_dir
if not init_dir:
init_dir = str(XMLS_PATH)
logging.info("menuaction.py file_open_xml()")
file_path = filedialog.askopenfilename(
initialdir=init_dir,
title="Open",
filetypes=(("XML Files", "*.xml"), ("All Files", "*")),
)
if file_path:
logging.info("opening xml: %s", file_path)
self.app.core.xml_file = file_path
self.app.core.xml_dir = str(os.path.dirname(file_path))
self.prompt_save_running_session()
@ -111,28 +110,30 @@ class MenuAction:
dialog.show()
def help_core_github(self):
logging.debug("Core github")
webbrowser.open_new("https://github.com/coreemu/core")
def help_core_documentation(self):
logging.debug("Core documentation")
webbrowser.open_new("http://coreemu.github.io/core/")
def session_options(self):
logging.debug("Click session options")
logging.debug("Click options")
dialog = SessionOptionsDialog(self.app, self.app)
dialog.show()
def session_change_sessions(self):
logging.debug("Click session change sessions")
logging.debug("Click change sessions")
dialog = SessionsDialog(self.app, self.app)
dialog.show()
def session_hooks(self):
logging.debug("Click session hooks")
logging.debug("Click hooks")
dialog = HooksDialog(self.app, self.app)
dialog.show()
def session_servers(self):
logging.debug("Click session emulation servers")
logging.debug("Click emulation servers")
dialog = ServersDialog(self.app, self.app)
dialog.show()
@ -141,24 +142,23 @@ class MenuAction:
dialog.show()
def show_about(self):
logging.debug("Click about")
dialog = AboutDialog(self.app, self.app)
dialog.show()
def throughput(self):
logging.debug("Click throughput")
if not self.app.core.handling_throughputs:
self.app.core.enable_throughputs()
else:
self.app.core.cancel_throughputs()
def copy(self, event: tk.Event = None):
logging.debug("copy")
self.app.canvas.copy()
def paste(self, event: tk.Event = None):
logging.debug("paste")
self.app.canvas.paste()
def config_throughput(self):
logging.debug("not implemented")
dialog = ThroughputDialog(self.app, self.app)
dialog.show()

View file

@ -1,6 +1,7 @@
"""
status bar
"""
import logging
import tkinter as tk
from tkinter import ttk
from typing import TYPE_CHECKING
@ -71,6 +72,7 @@ class StatusBar(ttk.Frame):
self.alerts_button.grid(row=0, column=4, sticky="ew")
def click_alerts(self):
logging.debug("Click alerts")
dialog = AlertsDialog(self.app, self.app)
dialog.show()

View file

@ -285,7 +285,7 @@ class Toolbar(ttk.Frame):
dialog.show()
def update_button(self, button: ttk.Button, image: "ImageTk", node_draw: NodeDraw):
logging.info("update button(%s): %s", button, node_draw)
logging.debug("update button(%s): %s", button, node_draw)
self.hide_pickers()
button.configure(image=image)
button.image = image
@ -293,7 +293,7 @@ class Toolbar(ttk.Frame):
self.app.canvas.node_draw = node_draw
def hide_pickers(self):
logging.info("hiding pickers")
logging.debug("hiding pickers")
if self.node_picker:
self.node_picker.destroy()
self.node_picker = None
@ -417,6 +417,7 @@ class Toolbar(ttk.Frame):
"""
redraw buttons on the toolbar, send node and link messages to grpc server
"""
logging.info("Click stop button")
self.app.canvas.hide_context()
self.app.statusbar.progress_bar.start(5)
self.time = time.perf_counter()
@ -434,7 +435,7 @@ class Toolbar(ttk.Frame):
messagebox.showerror("Stop Error", "Errors stopping session")
def update_annotation(self, image: "ImageTk.PhotoImage", shape_type: ShapeType):
logging.info("clicked annotation: ")
logging.debug("clicked annotation: ")
self.hide_pickers()
self.annotation_button.configure(image=image)
self.annotation_button.image = image