diff --git a/prototype2/common/Socket.cpp b/prototype2/common/Socket.cpp
index 52592d49fe3903c269258f3e396337337ce1c8ee..2d89c61f76be3623a54d2c30e91493b16145092b 100644
--- a/prototype2/common/Socket.cpp
+++ b/prototype2/common/Socket.cpp
@@ -17,6 +17,23 @@
 #define SEND_FLAGS 0
 #endif
 
+
+bool Socket::isValidIp(std::string ipAddress) {
+  struct sockaddr_in SockAddr;
+  return inet_pton(AF_INET, ipAddress.c_str(), &(SockAddr.sin_addr)) != 0;
+}
+
+std::string Socket::getHostByName(std::string &name) {
+  hostent * HostEntry = gethostbyname(name.c_str());
+  if (HostEntry == nullptr) {
+    throw std::runtime_error(fmt::format("Unable to resolve hostname {}", name));
+  } else { // Just return the first entry
+    auto IpAddress = inet_ntoa(*reinterpret_cast<in_addr*>(HostEntry->h_addr_list[0]));
+    LOG(IPC, Sev::Info, "Hostname resolved to {}", IpAddress);
+    return IpAddress;
+  }
+}
+
 Socket::Socket(Socket::type stype) {
   auto type = (stype == Socket::type::UDP) ? SOCK_DGRAM : SOCK_STREAM;
   auto proto = (stype == Socket::type::UDP) ? IPPROTO_UDP : IPPROTO_TCP;
@@ -70,28 +87,30 @@ int Socket::setNOSIGPIPE() {
 #endif
 }
 
-void Socket::setLocalSocket(const char *ipaddr, int port) {
+void Socket::setLocalSocket(const std::string ipaddr, int port) {
   // zero out the structures
   struct sockaddr_in localSockAddr;
   std::memset((char *)&localSockAddr, 0, sizeof(localSockAddr));
   localSockAddr.sin_family = AF_INET;
   localSockAddr.sin_port = htons(port);
 
-  int ret = inet_aton(ipaddr, &localSockAddr.sin_addr);
+  int ret = inet_aton(ipaddr.c_str(), &localSockAddr.sin_addr);
   if (ret == 0) {
-    LOG(IPC, Sev::Error, "invalid ip address {}", ipaddr);
-    throw std::runtime_error("setLocalSocket() - invalid ip");
+    auto Msg = fmt::format("setLocalSocket() - invalid ip address {}", ipaddr);
+    LOG(IPC, Sev::Error, Msg);
+    throw std::runtime_error(Msg);
   }
 
   // bind socket to port
   ret = bind(SocketFileDescriptor, (struct sockaddr *)&localSockAddr, sizeof(localSockAddr));
   if (ret != 0) {
-    LOG(IPC, Sev::Error, "bind failed - is port  {} already in use?", port);
-    throw std::runtime_error("setLocalSocket() - bind() failed");
+    auto Msg = fmt::format("setLocalSocket(): bind failed, is port {} already in use?", port);
+    LOG(IPC, Sev::Error, Msg);
+    throw std::runtime_error(Msg);
   }
 }
 
-void Socket::setRemoteSocket(const char *ipaddr, int port) {
+void Socket::setRemoteSocket(const std::string ipaddr, int port) {
   RemoteIp = ipaddr;
   RemotePort = port;
   // zero out the structures
@@ -99,10 +118,11 @@ void Socket::setRemoteSocket(const char *ipaddr, int port) {
   remoteSockAddr.sin_family = AF_INET;
   remoteSockAddr.sin_port = htons(port);
 
-  int ret = inet_aton(ipaddr, &remoteSockAddr.sin_addr);
+  int ret = inet_aton(ipaddr.c_str(), &remoteSockAddr.sin_addr);
   if (ret == 0) {
-    LOG(IPC, Sev::Error, "invalid ip address {}", ipaddr);
-    throw std::runtime_error("setRemoteSocket() - invalid ip");
+    auto Msg = fmt::format("etRemoteSocket(): invalid ip address {}", ipaddr);
+    LOG(IPC, Sev::Error, Msg);
+    throw std::runtime_error(Msg);
   }
 }
 
@@ -112,7 +132,7 @@ int Socket::connectToRemote() {
   std::memset((char *)&remoteSockAddr, 0, sizeof(remoteSockAddr));
   remoteSockAddr.sin_family = AF_INET;
   remoteSockAddr.sin_port = htons(RemotePort);
-  int ret = inet_aton(RemoteIp, &remoteSockAddr.sin_addr);
+  int ret = inet_aton(RemoteIp.c_str(), &remoteSockAddr.sin_addr);
   if (ret == 0) {
     LOG(IPC, Sev::Error, "invalid ip address {}", RemoteIp);
     throw std::runtime_error("connectToRemote() - invalid ip");
@@ -176,7 +196,7 @@ bool Socket::isValidSocket() {
 ///
 ///
 ///
-TCPTransmitter::TCPTransmitter(const char *ipaddr, int port) : Socket(Socket::type::TCP) {
+TCPTransmitter::TCPTransmitter(const std::string ipaddr, int port) : Socket(Socket::type::TCP) {
   setRemoteSocket(ipaddr, port);
   setNOSIGPIPE();
   connectToRemote();
diff --git a/prototype2/common/Socket.h b/prototype2/common/Socket.h
index 6e1bd287a00b795a41bf682a04d6ba500ddd6af3..2616f35d81f3938466a5ff6e8fdfd9d6e0c6c276 100644
--- a/prototype2/common/Socket.h
+++ b/prototype2/common/Socket.h
@@ -13,6 +13,7 @@
 #include <cassert>
 #include <cinttypes>
 #include <sys/socket.h>
+#include <netinet/ip.h>
 
 /// BSD Socket abstractions for TCP and UDP transmitters and receivers
 class Socket {
@@ -22,12 +23,22 @@ public:
 
   class Endpoint {
   public:
-    const char *ipaddr;
+    const std::string ipaddr;
     uint16_t port;
-    Endpoint(const char *ip_address, uint16_t port_number)
+    Endpoint(const std::string ip_address, uint16_t port_number)
         : ipaddr(ip_address), port(port_number) {}
   };
 
+  /// \brief Is this a dotted quad ip address?
+  /// Valid addresses must be of the form 'a.b.d.c' where
+  /// a-d can range from 0 to 255
+  static bool isValidIp(std::string ipAddress);
+
+  /// \brief Return dotted quad by resolving hostname
+  /// Essentially a wrapper for gethostbyname() returning
+  /// the first entry in the ip address table
+  static std::string getHostByName(std::string &name);
+
   /// Create a socker abstraction of type UDP or TCP
   Socket(Socket::type type);
 
@@ -47,10 +58,10 @@ public:
   int setNOSIGPIPE();
 
   /// Specify ip address of interface to receive data on and port number to listen on
-  void setLocalSocket(const char *ipaddr, int port);
+  void setLocalSocket(const std::string ipaddr, int port);
 
   /// Specify ip address and port number of remote end
-  void setRemoteSocket(const char *ipaddr, int port);
+  void setRemoteSocket(const std::string ipaddr, int port);
 
   /// Connect (TCP only) to remote endpoint
   int connectToRemote();
@@ -61,12 +72,12 @@ public:
   /// Send data in buffer with specified length
   int send(void *dataBuffer, int dataLength);
 
-  /// \brief To check is data can be transmitted or received
+  /// \brief To check if data can be transmitted or received
   bool isValidSocket();
 
 private:
   int SocketFileDescriptor{-1};
-  const char * RemoteIp;
+  std::string RemoteIp;
   int RemotePort;
   struct sockaddr_in remoteSockAddr;
 
@@ -97,7 +108,7 @@ public:
 class TCPTransmitter : public Socket {
 public:
   ///
-  TCPTransmitter(const char *ip, int port);
+  TCPTransmitter(const std::string ip, int port);
 
   ///
   int senddata(char *buffer, int len);
diff --git a/prototype2/common/StatPublisher.cpp b/prototype2/common/StatPublisher.cpp
index 05777679482aca49bf2ac1577099c853a88145c1..c2d9b5d35b0120321e8b14c5e5647d524ef685dc 100644
--- a/prototype2/common/StatPublisher.cpp
+++ b/prototype2/common/StatPublisher.cpp
@@ -11,6 +11,9 @@
 
 ///
 StatPublisher::StatPublisher(std::string ip, int port) :IpAddress(ip), TCPPort(port) {
+  if (not Socket::isValidIp(IpAddress)) {
+    IpAddress = Socket::getHostByName(IpAddress);
+  }
   StatDb.reset(new TCPTransmitter(IpAddress.c_str(), TCPPort));
 }
 
diff --git a/prototype2/common/StatPublisher.h b/prototype2/common/StatPublisher.h
index c4d194f3046e2688bff919f90687dc4a6cda038d..624ca09e06ccc6ae86ea43e173210347e599577a 100644
--- a/prototype2/common/StatPublisher.h
+++ b/prototype2/common/StatPublisher.h
@@ -17,7 +17,7 @@
 
 class StatPublisher {
 public:
-  /// \brief Connect to a Carbon/Graphite server bu ip address and tcp port
+  /// \brief Connect to a Carbon/Graphite server by ip address/hostname and tcp port
   StatPublisher(std::string ip, int port);
 
   /// \brief Send detector metrics to Carbon/Graphite server given additional stats
diff --git a/prototype2/common/test/SocketTest.cpp b/prototype2/common/test/SocketTest.cpp
index fb009c6e6115618de158ba4782b5a5393f01733a..7aa5d80d411a676d6b842d406c1f797b075d9b2b 100644
--- a/prototype2/common/test/SocketTest.cpp
+++ b/prototype2/common/test/SocketTest.cpp
@@ -3,6 +3,8 @@
 #include <prototype2/test/TestBase.h>
 #include <common/Socket.h>
 
+std::vector<std::string> ipOk = {"0.0.0.0", "10.10.10.10", "127.0.0.1", "224.1.2.3", "255.255.255.255"};
+std::vector<std::string> ipNotOk = {"a.0.0.0", "1.2.3", "1.2", "", "127.0.0.256", "metrics"};
 
 class SocketTest : public ::testing::Test {
 protected:
@@ -31,6 +33,32 @@ TEST_F(SocketTest, SendUninitialized) {
   ASSERT_FALSE(tcpsocket.isValidSocket());
 }
 
+TEST_F(SocketTest, ValidInvalidIp) {
+  for (auto ipaddr : ipOk) {
+    ASSERT_TRUE(Socket::isValidIp(ipaddr));
+    auto res = Socket::getHostByName(ipaddr);
+    ASSERT_TRUE(res == ipaddr);
+  }
+  for (auto ipaddr : ipNotOk) {
+    ASSERT_FALSE(Socket::isValidIp(ipaddr));
+  }
+}
+
+TEST_F(SocketTest, GetHostByName) {
+  std::string name {"localhost"};
+  auto res = Socket::getHostByName(name);
+  ASSERT_TRUE(res == "127.0.0.1");
+  for (auto ipaddr : ipOk) {
+    auto res = Socket::getHostByName(ipaddr);
+    ASSERT_TRUE(res == ipaddr);
+  }
+  // Checking weird case - not sure if this is right
+  // this step can be deleted if it causes problems later
+  std::string weirdIp {"8.8.8"};
+  res = Socket::getHostByName(weirdIp);
+  ASSERT_TRUE(res == "8.8.0.8");
+}
+
 int main(int argc, char **argv) {
   testing::InitGoogleTest(&argc, argv);
   return RUN_ALL_TESTS();