3
A brief file description
5
@section license License
7
Licensed to the Apache Software Foundation (ASF) under one
8
or more contributor license agreements. See the NOTICE file
9
distributed with this work for additional information
10
regarding copyright ownership. The ASF licenses this file
11
to you under the Apache License, Version 2.0 (the
12
"License"); you may not use this file except in compliance
13
with the License. You may obtain a copy of the License at
15
http://www.apache.org/licenses/LICENSE-2.0
17
Unless required by applicable law or agreed to in writing, software
18
distributed under the License is distributed on an "AS IS" BASIS,
19
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20
See the License for the specific language governing permissions and
21
limitations under the License.
24
/***************************************************************************
28
***************************************************************************/
38
#include "LogFormat.h"
39
#include "LogBuffer.h"
41
#include "LogObject.h"
42
#include "LogConfig.h"
45
#if defined(IOCORE_LOG_COLLATION)
46
#include "LogCollationClientSM.h"
52
/*-------------------------------------------------------------------------
54
-------------------------------------------------------------------------*/
56
LogHost::LogHost(char *object_filename, uint64_t object_signature)
57
: m_object_filename(xstrdup(object_filename))
58
, m_object_signature(object_signature)
67
#if defined (IOCORE_LOG_COLLATION)
68
, m_log_collation_client_sm(NULL)
73
LogHost::LogHost(const LogHost & rhs)
74
: m_object_filename(xstrdup(rhs.m_object_filename))
75
, m_object_signature(rhs.m_object_signature)
77
, m_ipstr(xstrdup(rhs.m_ipstr))
78
, m_name(xstrdup(rhs.m_name))
84
#if defined (IOCORE_LOG_COLLATION)
85
, m_log_collation_client_sm(NULL)
88
create_orphan_LogFile_object();
94
xfree(m_object_filename);
98
// There are 3 ways to establish a LogHost:
99
// - by "hostname:port" or IP:port", where IP is a string of the
100
// form "xxx.xxx.xxx.xxx".
101
// - by specifying a hostname and a port (as separate arguments).
102
// - by specifying an ip and a port (as separate arguments).
106
LogHost::set_name_port(char *hostname, unsigned int pt)
108
if (!hostname || hostname[0] == 0) {
109
Note("Cannot establish LogHost with NULL hostname");
113
clear(); // remove all previous state for this LogHost
115
m_ip = 0; // make sure ip is 0 for iocore
116
#if !defined(IOCORE_LOG_COLLATION)
117
m_ip = LogUtils::ip_from_host(hostname);
118
m_ipstr = (char *) xmalloc(32);
119
LogUtils::ip_to_str(m_ip, m_ipstr, 32);
121
m_name = xstrdup(hostname);
124
Debug("log-host", "LogHost established as %s:%u", name(), port());
126
create_orphan_LogFile_object();
131
LogHost::set_ipstr_port(char *ipstr, unsigned int pt)
133
if (!ipstr || ipstr[0] == 0) {
134
Note("Cannot establish LogHost with NULL ipstr");
138
clear(); // remove all previous state for this LogHost
140
m_ip = htonl(LogUtils::str_to_ip(ipstr));
141
m_ipstr = xstrdup(ipstr);
142
m_name = xstrdup(ipstr);
145
Debug("log-host", "LogHost established as %s:%u", name(), port());
147
create_orphan_LogFile_object();
152
LogHost::set_name_or_ipstr(char *name_or_ip)
156
if (name_or_ip && name_or_ip[0] != 0) {
157
SimpleTokenizer tok(name_or_ip, ':');
158
char *n = tok.getNext();
160
char *p = tok.getNext();
161
unsigned int port = (p ? (unsigned int) atoi(p) : Log::config->collation_port);
163
if (LogUtils::valid_ipstr_format(n)) {
164
retVal = set_ipstr_port(n, port);
166
retVal = set_name_port(n, port);
173
bool LogHost::connected(bool ping)
175
if (m_connected && m_sock && m_sock_fd >= 0) {
176
if (m_sock->is_connected(m_sock_fd, ping)) {
183
bool LogHost::connect()
186
Note("Cannot connect to LogHost; host IP has not been established");
190
if (connected(PING)) {
194
Debug("log-host", "Connecting to LogHost %s:%u", name(), port());
196
disconnect(); // make sure connection members are initialized
198
if (m_sock == NULL) {
199
m_sock = NEW(new LogSock());
200
ink_assert(m_sock != NULL);
202
m_sock_fd = m_sock->connect(m_ip, m_port);
204
Note("Connection to LogHost %s:%u failed", name(), port());
209
if (!authenticated()) {
210
Note("Authentication to LogHost %s:%u failed", name(), port());
219
LogHost::disconnect()
221
if (m_sock && m_sock_fd >= 0) {
222
m_sock->close(m_sock_fd);
229
LogHost::write(LogBuffer * lb, size_t * to_disk, size_t * to_net, size_t * to_pipe)
231
NOWARN_UNUSED(to_pipe);
233
Note("Cannot write LogBuffer to LogHost %s; LogBuffer is NULL", name());
236
LogBufferHeader *buffer_header = lb->header();
237
if (buffer_header == NULL) {
238
Note("Cannot write LogBuffer to LogHost %s; LogBufferHeader is NULL", name());
241
if (buffer_header->entry_count == 0) {
245
#if !defined(IOCORE_LOG_COLLATION)
247
// make sure we're connected & authenticated
249
if (!connected(NOPING)) {
251
Note("Cannot write LogBuffer to LogHost %s; not connected", name());
252
return orphan_write(lb);
255
// try sending the logbuffer
257
int bytes_to_send, bytes_sent;
258
bytes_to_send = buffer_header->byte_count;
259
lb->convert_to_network_order();
260
bytes_sent = m_sock->write(m_sock_fd, buffer_header, bytes_to_send);
261
if (bytes_to_send != bytes_sent) {
262
Note("Bad write to LogHost %s; bad send count %d/%d", name(), bytes_sent, bytes_to_send);
264
lb->convert_to_host_order();
265
return orphan_write(lb);
268
Debug("log-host", "%d bytes sent to LogHost %s:%u", bytes_sent, name(), port());
269
// BUGBUG:: fix this, Log Collation should work on NT as well
270
SUM_DYN_STAT(log_stat_bytes_sent_to_network_stat, bytes_sent);
273
#else // !defined(IOCORE_LOG_COLLATION)
275
// make a copy of our log_buffer
276
int buffer_header_size = buffer_header->byte_count;
277
LogBufferHeader *buffer_header_copy = (LogBufferHeader *) NEW(new char[buffer_header_size]);
278
ink_assert(buffer_header_copy != NULL);
280
memcpy(buffer_header_copy, buffer_header, buffer_header_size);
281
LogBuffer *lb_copy = NEW(new LogBuffer(lb->get_owner(),
282
buffer_header_copy));
283
ink_assert(lb_copy != NULL);
285
// create a new collation client if necessary
286
if (m_log_collation_client_sm == NULL) {
287
m_log_collation_client_sm = NEW(new LogCollationClientSM(this));
288
ink_assert(m_log_collation_client_sm != NULL);
290
// send log_buffer; orphan if necessary
291
int bytes_sent = m_log_collation_client_sm->send(lb_copy);
292
if (bytes_sent <= 0) {
294
bytes_sent = orphan_write_and_delete(lb_copy, to_disk);
295
#if defined(LOG_BUFFER_TRACKING)
296
Debug("log-buftrak", "[%d]LogHost::write - orphan write complete", lb_copy->header()->id);
297
#endif // defined(LOG_BUFFER_TRACKING)
299
Note("Starting dropping log buffer due to overloading");
305
*to_net += bytes_sent;
311
#endif // !defined(IOCORE_LOG_COLLATION)
315
LogHost::create_orphan_LogFile_object()
317
delete m_orphan_file;
319
const char *orphan_ext = "orphan";
320
unsigned name_len = (unsigned) (strlen(m_object_filename) + strlen(name()) + strlen(orphan_ext) + 16);
321
char *name_buf = (char *) xmalloc(name_len);
322
ink_assert(name_buf != NULL);
323
// NT: replace ':'s with '-'s. This change is necessary because
324
// NT doesn't like filenames with ':'s in them. ^_^
325
snprintf(name_buf, name_len, "%s%s%s-%u.%s",
326
m_object_filename, LOGFILE_SEPARATOR_STRING, name(), port(), orphan_ext);
328
// should check for conflicts with orphan filename
330
m_orphan_file = NEW(new LogFile(name_buf, NULL, ASCII_LOG, m_object_signature));
331
ink_assert(m_orphan_file != NULL);
337
LogHost::orphan_write(LogBuffer * lb, size_t * to_file)
339
if (!Log::config->logging_space_exhausted) {
340
Debug("log-host", "Sending LogBuffer to orphan file %s", m_orphan_file->get_name());
341
return m_orphan_file->write(lb, to_file);
343
return 0; // nothing written
348
LogHost::orphan_write_and_delete(LogBuffer * lb, size_t * to_disk)
350
int bytes = orphan_write(lb, to_disk);
351
// done with the buffer, delete it
359
LogHost::display(FILE * fd)
361
fprintf(fd, "LogHost: %s:%u, %s\n", name(), port(), (connected(NOPING)) ? "connected" : "not connected");
367
// close an established connection and clear the state of this host
378
delete m_orphan_file;
387
m_orphan_file = NULL;
390
bool LogHost::authenticated()
392
if (!connected(NOPING)) {
393
Note("Cannot authenticate LogHost %s; not connected", name());
397
Debug("log-host", "Authenticating LogHost %s ...", name());
399
auth_key = Log::config->collation_secret;
401
auth_key_len = (unsigned)::strlen(auth_key) + 1; // incl null
403
bytes = m_sock->write(m_sock_fd, auth_key, auth_key_len);
404
if ((unsigned) bytes != auth_key_len) {
405
Debug("log-host", "... bad write on authenticate");
409
Debug("log-host", "... authenticated");
413
/*-------------------------------------------------------------------------
415
-------------------------------------------------------------------------*/
417
LogHostList::LogHostList()
421
LogHostList::~LogHostList()
427
LogHostList::add(LogHost * object, bool copy)
429
ink_assert(object != NULL);
431
m_host_list.enqueue(NEW(new LogHost(*object)));
433
m_host_list.enqueue(object);
441
for (LogHost * host = first(); host; host = next(host)) {
451
while ((host = m_host_list.dequeue())) {
457
LogHostList::write(LogBuffer * lb, size_t * to_disk, size_t * to_net, size_t * to_pipe)
460
for (LogHost * host = first(); host; host = next(host)) {
461
int bytes = host->write(lb, to_disk, to_net, to_pipe);
463
total_bytes += bytes;
469
LogHostList::display(FILE * fd)
471
for (LogHost * host = first(); host; host = next(host)) {
476
bool LogHostList::operator==(LogHostList & rhs)
480
for (host = first(); host; host = next(host)) {
483
for (rhs_host = rhs.first(); rhs_host; rhs_host = next(host)) {
484
if ((host->port() == rhs_host->port() &&
485
(host->ip() && rhs_host->ip() &&
486
(host->ip() == rhs_host->ip()))) ||
487
(host->name() && rhs_host->name() &&
488
(strcmp(host->name(), rhs_host->name()) == 0)) ||
489
(host->ipstr() && rhs_host->ipstr() && (strcmp(host->ipstr(), rhs_host->ipstr()) == 0))) {
493
if (rhs_host == NULL) {
501
LogHostList::do_filesystem_checks()
503
for (LogHost * host = first(); host; host = next(host)) {
504
if (host->do_filesystem_checks() < 0) {