分类:未分类


elastic stack 使用redis作为日志缓冲


直接上步骤:

1、首先建立一个配置文件,将output的数据写到redis中,而不是ES了。配置文件示例:

input {
    stdin { }
}
output {
    redis {
        host => "192.168.1.100"  #redis服务器地址
        port => "6379"  #redis服务端口
        db => "5"  #使用redis第五个库,用其他库也可以
        data_type => "list"  #用list类型
        key => "demo"  #存储的key名,可自定义自己喜欢的
    }
}

 

2、指定配置文件然后运行Logstash,然后我们在标准输入中随便写点什么东西,这个时候输入的数据都会提交到redis中。登录redis后使用info命令可以查看keyspace相关信息,可以看到db5的keys数量有了变化,我们切换到db5再来看看

select 5
keys *

 

3、通过keys *命令可以看到有了一个key叫做demo,这个就是配置文件里设置的key名,使用LLEN demo可以看到该key的长度,input如果输入了100行,那么这个key就应该有100行

4、再次建立一个配置文件,这次input是从第一步里的redis里读取数据,然后output到ES中

input {
    redis {
        host => "192.168.1.100"  
        port => "6379"  
        db => "5"  
        data_type => "list"
        key => "demo" 
    }
}
output {
    elasticsearch {
        hosts => ["192.168.0.100:9200"]
        index => "redis-demo-%{+YYYY.MM.dd}"
    }
}

 

5、运行该配置文件后去redis看看,之前的队列因为被output到了ES中,所以队列会消失掉或者是迅速减少长度

下面是一个改造后的配置文件,更符合实际需求

input {
    file {
        path => "/var/log/messages"
        type => "system"
}
output {
    if [type] == "system" {
        redis {
          host => "192.168.1.100"
          port => "6379"
          db => "5" 
          data_type => "list" 
          key => "system"
    }
}

linux shell命名管道FIFO


在shell脚本中,我们想要实现多进程高并发,最简单的方法是把命令丢到后台去,如果量不大的话,没问题。 但是如果有几百个进程同一时间丢到后台去就很恐怖了,对于服务器资源的消耗非常大,甚至导致宕机。

那有没有好的解决方案呢? 当然有!

我们先来学习下面的常识。

1 文件描述符

文件描述符(缩写fd)在形式上是一个非负整数。实际上,它是一个索引值,指向内核为每一个进程所维护的该进程打开文件的记录表。当程序打开一个现有文件或者创建一个新文件时,内核向进程返回一个文件描述符。每一个unix进程,都会拥有三个标准的文件描述符,来对应三种不同的流:

除了上面三个标准的描述符外,我们还可以在进程中去自定义其他的数字作为文件描述符,后面例子中会出现自定义数字。每一个文件描述符会对应一个打开文件,同时,不同的文件描述符也可以对应同一个打开文件;同一个文件可以被不同的进程打开,也可以被同一个进程多次打开。

我们可以写一个测试脚本/tmp/test.sh,内容如下:

#!/bin/bash

echo “该进程的pid为$$”

exec 1>/tmp/test.log 2>&1

ls -l /proc/$$/fd/

执行该脚本 sh /tmp/test.sh,然后查看/tmp/test.log内容为:

总用量 0

lrwx—— 1 root root 64 11月 22 10:26 0 -> /dev/pts/3

l-wx—— 1 root root 64 11月 22 10:26 1 -> /tmp/test.log

l-wx—— 1 root root 64 11月 22 10:26 2 -> /tmp/test.log

lr-x—— 1 root root 64 11月 22 10:26 255 -> /tmp/test.sh

lrwx—— 1 root root 64 11月 22 10:26 3 -> socket:[196912101]

其中0为标准输入,也就是当前终端pts/3,1和2全部指向到了/tmp/test.log,另外两个数字,咱们暂时不关注。

2 命名管道

我们之前接触过的管道“1”,其实叫做匿名管道,它左边的输出作为右边命令的输入。这个匿名管道只能为两边的命令提供服务,它是无法让其他进程连接的。

实际上,这两个进程(cat和less)并不知道管道的存在,它们只是从标准文件描述符中读取数据和写入数据。

另外一种管道叫做命名管道,英文(First In First Out,简称FIFO)。

FIFO本质上和匿名管道的功能一样,只不过它有一些特点:

1)在文件系统中,FIFO拥有名称,并且是以设备特俗文件的形式存在的;

2)任何进程都可以通过FIFO共享数据;

3)除非FIFO两端同时有读与写的进程,否则FIFO的数据流通将会阻塞;

4)匿名管道是由shell自动创建的,存在于内核中;而FIFO则是由程序创建的(比如mkfifo命令),存在于文件系统中;

5)匿名管道是单向的字节流,而FIFO则是双向的字节流;

有了上面的基础知识储备后,下面我们来用FIFO来实现shell的多进程并发控制。

需求背景:

领导要求小明备份数据库服务器里面的100个库(数据量在几十到几百G),需要以最快的时间完成(5小时内),并且不能影响服务器性能。

需求分析:

由于数据量比较大,单个库备份时间少则10几分钟,多则几个小时,我们算平均每个库30分钟,若一个库一个库的去备份,则需要3000分钟,相当于50个小时。很明显不可取。但全部丢到后台去备份,100个并发,数据库服务器也无法承受。所以,需要写一个脚本,能够控制并发数就可以实现了。

控制并发的shell脚本示例:

#!/bin/sh

function a_sub {
    sleep 2;
    endtime=`date +%s`
    sumtime=$[$endtime-$starttime]
    echo "我是$i,运行了2秒,整个脚本已经执行了$sumtime秒"
}

starttime=`date +%s`
export starttime

##其中$$为该进程的pid
tmp_fifofile="/tmp/$$.fifo"

##创建命名管道
mkfifo $tmp_fifofile

##把文件描述符6和FIFO进行绑定
exec 6<>$tmp_fifofile

##绑定后,该文件就可以删除了
rm -f $tmp_fifofile

##并发量为8,用这个数字来控制并发数
thread=8

for ((i=0;i<$thread;i++));
do
    ##写一个空行到管道里,因为管道文件的读取以行为单位
    echo >&6
done

##循环100次,相当于要备份100个库
for ((i=0;i<100;i++))
do
    ##读取管道中的一行,每次读取后,管道都会少一行
    read -u6
    {
        a_sub || {echo "a_sub is failed"}
        ##每次执行完a_sub函数后,再增加一个空行,这样下面的进程才可以继续执行
        echo >&6
    } & ##这里要放入后台去,否则并发实现不了
done

##这里的wait意思是,需要等待以上所有操作(包括后台的进程)都结束后,再往下执行。
wait

##关闭文件描述符6的写
exec 6>&-

 

vim的加密功能


一、 利用 vim 加密:

优点:加密后,如果不知道密码,就看不到明文,包括root用户也看不了;
缺点:很明显让别人知道加密了,容易让别人把加密的文件破坏掉,包括内容破坏和删除;

vim编辑器相信大家都很熟悉了吧,vim里有一个命令是给文件加密的,举个例子:

1) 首先在root主目录/root/下建立一个实验文件text.txt:
#  vim  text.txt

2) 进到编辑模式,输入完内容后按ESC,然后输入:X(注意是大写的X),回车;

3) 这时系统提示让你输入密码,2次,如下所示:
输入密码: *******
请再输入一次: *******

4) 保存后退出,现在这个文件已经加密了;

5) 用cat或more查看文件内容,显示为乱码;用 vim重新编辑这个文件,会提示输入密码,如果输入的密码不正确,同样会显示为乱码!
注意:文件加密后,千万别忘了密码!

二、 vim编辑加密的文件(前提是你知道加密的密码):

1)  用 vim 打开文件如text.txt,要输入正确的密码,然后在编辑时,将密码设置为空,方法是输入下面的命令:
:set key=
然后直接回车,保存文件后,文件已经解密了。

2) 或者这样也行:
在正确打开文件后用 “:X” 指令,然后给一个空密码也可以。保存用“wq!”保存。
两种方法实际上效果是一样的。

apache rewrite死循环的问题


需求背景是: 把所有请求都转发到/111/目录下面,比如当访问 www.aminglinux.com/1.html时,应该跳转到www.aminglinux.com/111/1.html

核心配置语句是

RwriteRule ^(.*)$  /111/$1 [R,L]

使用curl测试,没有问题,但是使用浏览器访问时,出现了无限循环。
本来访问的是www.aminglinux.com/1.html时,结果变成了www.aminglinux.com/111/111/111/111/…..

解决该问题的方法是,加一个条件

RewriteCond   %{REQUEST_URI} !^/111

RewriteRule ^(.*) /111/$1 [R,L]

关于mysql优化的一些心得


先介绍下服务器架构及配置8核8G,10M带宽Centos6.5,64位,系统的架构为

Nginx 1.8.1,PHP  5.3.29,Mysql  5.5.42。

一电商网站后台查询订单时,经常php超时,导致php报错。以下是排查过程。

1、php执行超时,首先我们想到的就是php.ini文件中max_execution_time =  #把默认的值调大。

2、然后在后台执行订单查询php不报错了,但是查询耗时较长,用时65s。而且一些表成锁死状态碎片比较多,本人对mysql数据库优化不是很了解,于是请教了铭哥下,铭哥给出的答复是:一般mysql调优主要是根据慢查询日志去优化sql语句,my.cnf里面可调整的东西不多,而且效果也不明显。 下面就是调整参数,分析mysql慢查询日志。

3、mysql参数优化,主要调整的参数根据机器性能来调整,如果你对参数不是很了解,建议不要盲目的调。给大家一篇参数调整的文章 http://ask.apelearn.com/question/5758 (看第5条)

把一些配置参数修改好后重启mysqld服务,由原来的65s变成了十几秒。效果还是不是很理想,查看了下mysql默认引擎为MyISAM,决定把引擎改为Innodb。具体操作过程如下:

4、导出shop数据库的表结构

mysqldump -d -uxxx -p shop > shop_table.sql

其中-d参数表示不导出数据,只导出表结构

5、替换shop_table.sql里的MyISAM为INNODB

sed -i ‘s/MyISAM/INNODB/g’ shop_table.sql

6、新建数据库shop_new库,并导入表结构

mysql > create database shop_new;

mysql -uroot -p shop_new < shop_table.sql可以通过show table status来检查表引擎是否为INNODB。

7、导出shop的数据

mysqldump -t -uroot -p shop > shop_data.sql其中-t参数表示只导数据,不导表结构

8、导入数据到shop_new

mysql -uroot -p shop_new < shop_data.sql

9、 查看慢查询日志来定位mysql哪条语句执行慢,然后建立索引,优化sql执行语句。这台机器的慢查询日志片段,供大家参考

# Time: 160303 12:12:38

# User@Host: root[root] @  [10.165.34.182]

# Query_time: 10.145685  Lock_time: 0.000395 Rows_sent: 1  Rows_examined: 24306970

use shop;

SET timestamp=1456978358;

SELECT COUNT(*) FROM `shop`.`ecs_order_info` o LEFT JOIN`shop`.`ecs_users` u ON o.user_id = u.user_id LEFT JOIN `shop`.`ecs_affiliate_log` a ON o.order_id = a.order_id WHERE o.user_id > 0 AND (u.parent_id > 0 AND o.is_separate = 0 OR o.is_separate > 0);

# Time: 160303 12:12:44

# User@Host: root[root] @  [10.165.34.182]

# Query_time: 6.073441  Lock_time: 0.000152 Rows_sent: 15  Rows_examined: 24314767

SET timestamp=1456978364;

SELECT o.*, a.log_id, a.user_id as suid,  a.user_name as auser, a.money, a.point, a.separate_type,u.parent_id as up FROM `shop`.`ecs_order_info` o LEFT JOIN`shop`.`ecs_users` u ON o.user_id = u.user_id LEFT JOIN `shop`.`ecs_affiliate_log` a ON o.order_id = a.order_id WHERE o.user_id > 0 AND (u.parent_id > 0 AND o.is_separate = 0 OR o.is_separate > 0)  ORDER BY order_id DESC LIMIT 0,15;

通过慢日志发现其中有几个表查询耗时较长,下面就是把这个查询慢的表建立索引。用到的软件 NAvicat,对查询慢的表进行设计,增加索引。

 

根据 explain  的解释,查看下  索引是否建立,一般都是 这样调整 就行。

 

修改完后重启mysql 服务,查询时间从65s,缩短到 0.017407 秒

git,github,gitlab


如果初次接触git的朋友一定搞不清git,github以及gitlab这几个概念。

git如果不知道是啥,那你总知道svn是啥吧。什么?svn也不知道?那只好辛苦你动动手搜一下了。

git用一句话介绍:它是一个分布式的版本管理工具。然后我从网上找了两张图来对比svn和git的最主要的差异——分布式。

 

从上面两个图,可以看出使用svn的版本变化数据都是存在于服务端的,最终控制中心只有一个。而git,每一个客户端都可以作为一个版本管理中心,当然它也需要有一个公共的总控制点。

再给大家举一个例子吧,比如我和朋友一起开发一个软件,这个软件有很多代码片段,所以改动也比较频繁。如果使用svn,那我们无论谁每改动一段代码都要推送到svn中心去,而为了保证代码统一,其中一个人只要因为推送新的代码变动了控制中心,另一个人都要把改动的地方拉取到自己的电脑。所以这样就比较麻烦了。

而使用git时,我和朋友都可以在自己电脑上搞一个git控制中心,我们电脑里面的代码可以不一致,只需要用自己的git管理自己的那一部分代码。而git服务端只是用来合并我和朋友的最终版本代码的,平时的小改动由我们自己电脑里面的控制中心来管理,git服务端不用关心。

下面我用一个公司老总管理员工的例子再来总结一下svn和git的差异。svn架构里面的管理者比较独裁,不信任任何人,所有的事情都是亲力亲为,它宁愿管理所有员工也不设置下级管理者。

而git架构里面的老总比较明智,他比较偷懒,只管大事情,小事情都是交给下面的小leader去搞定的。每个小leader去管理自己的下属也不用关心其他leader的事情。但是所有leader都需要不定期向大boss汇报一下近期的情况。

github,是一个web界面的git管理平台,也就是说它底层的技术驱动依然是git。一句话区分,git是管理工具,github是在线的基于git的平台(或者叫做服务)。github的角色也就是我们上面例子中的大boss。github是公开的,谁都可以注册账号,并创建自己的项目,大部分项目以代码为主,比如wordpress、discuz都是托管在github里面的,当然还有好多好多开源的软件。

既然github是一个公共的,在线的提供服务的平台,那企业就可以把公司内部的代码托管在这里,为了安全我们可以选择付费服务,定制个性化方案。但毕竟github在国外,要想获得更好的功能还需要花钱,小企业或者个人用户自然是不愿意去开销了。

还好又一款开源的软件可以帮我们搭建一套类似github的平台,这就是接下来我要介绍的gitlab。 gitlab适合企业内部构建私有代码管理平台,它有健全的权限控制系统和各种强大的功能,很赞。

所以,gitlab和github一样,也是一个基于git的提供web界面的代码管理平台。

redis持久化rdb和aof


redis如果不把数据做持久化,则是把数据存储在内存里面的,所以速度很快。而持久化的目的是为了保证数据安全。redis提供了两种持久化的方案:rdb和appendonly(简称aof)。

简单讲,rdb形式就是把具体的数据(key以及value)存到到一个文件中;而aof这种是把操作过程以日志的形式存到一个文件里,类似于mysql的bin-log。

rdb,需要定义dir,也就是数据所存放的目录,其实aof文件也会放到这个目录下面,而dbfilename则定义了rdb文件的名字。配置文件中有一个参数“save”来定义redis按照什么样的规则把内存中的数据刷新到磁盘上的rdb文件里。当然我们也可以用命令“save”或者“bgsave”来手动把内存里面的数据更新到磁盘上。如果想要关闭rdb持久化,可以直接把save参数的值设置为空,即save “”,或者在redis-cli命令行里面执行:config set save “”.

aof,有一个参数是控制它的开关。“appendonly yes” 只有这个是yes时,才会在dir目录中生成一个aof文件,文件名字默认是appendonly.aof,当然我们可以用appendfilename参数去修改它。

对于aof文件,如果我们不做特殊操作,它会无限制增长,以至于把磁盘撑爆。如果业务对redis数据没有那么高的要求的话,可以不用开启aof。另外有一个方法可以实现aof文件的优化,就是执行命令 BGREWRITEAOF,这样就会重写aof文件,最终将aof文件的体积减小。这个过程可能会耗费一定的资源,建议在凌晨执行。

最后,再来总结一下。rdb并不会实时把内存数据写到磁盘中,意外断电时会丢一部分数据的,但是aof就安全得多,它几乎是实时记录日志的,通过参数appendfsync控制,默认everysec是一秒记录一次。两种持久化的方式是可以并存的,当数据恢复时,以aof优先。

CGI、FastCGI与php-fpm


这几个概念是在lamp、lnmp架构我们遇到的。好多同学对这几个概念一直不明白。下面我就简单说说我的理解。

在web开发领域中有个大概念大家必须要搞清楚,那就是静态和动态。静态就是一些诸如html、图片、js、css等请求元素,它们的特点是不需要和其他资源(比如数据库)打交道,可以直接由web server(httpd、nginx等)处理。如下图:

 

而动态则是需要和数据库等资源打交道的请求,在lamp/lnmp架构中,需要一个中间件(PHP解释器)去解析php代码,然后和mysql数据库打交道。如图:

当Web Server收到 index.php 这个请求后,会启动对应的 CGI 程序,这里就是PHP的解析器。接下来PHP解析器会解析php.ini文件,初始化执行环境,然后处理请求,再以规定CGI规定的格式返回处理后的结果,退出进程,Web server再把结果返回给浏览器。这就是一个完整的动态PHP Web访问流程,接下来再引出这些概念,就好理解多了。

我们再来解释几个概念:

CGI:是 Web Server 与 Web Application 之间数据交换的一种协议。

FastCGI:同 CGI,是一种通信协议,但比 CGI 在效率上做了一些优化。同样,SCGI 协议与 FastCGI 类似。

PHP-CGI:是 PHP (Web Application)对 Web Server 提供的 CGI 协议的接口程序。

PHP-FPM:是 PHP(Web Application)对 Web Server 提供的 FastCGI 协议的接口程序,额外还提供了相对智能一些任务管理。

WEB 中,Web Server 一般指Apache、Nginx、IIS、Lighttpd、Tomcat等服务器,Web Application 一般指PHP、Java、Asp.net等应用程序。

在这里我们还要了解另外一种方式 —— Apache的Module方式。 lamp架构中,php是以一个模块(libphp5.so)的方式被httpd调用的,这个模块是通过sapi把数据交给了php的解释器。

SAPI提供了一个和外部通信的接口,有点类似于socket,使得PHP可以和其他应用进行交互数据(apache,nginx等)。php默认提供了很多种SAPI,常见的提供给apache和nginx的php5_module、CGI、FastCGI,给IIS的ISAPI,以及Shell的CLI。

最后再来说一说,FastCGI为什么比CGI优秀。

不管是CGI还是FastCGI都是专门用来和WEB服务器打交道的,web服务器收到用户请求,就会把请求提交给cgi/fastcgi程序(如php-cgi),cgi/fastcgi程序根据请求提交的参数作应处理(解析php),然后输出标准的html语句,返回给web服服务器,WEB服务器再返回给客户端,这就是普通cgi/fastcgi的工作原理。

cgi和fastcgi不同在于,cgi需要在每一次WEB服务器把请求交给它时都需要启动一次进程,然后处理结束后还要关闭进程。这样当并发量很大时,就会造成服务器资源耗费严重。而fastcgi则为常驻进程,也就是说进程启动后会一直在线,不用频繁开启和关闭。另外fastcgi还支持分布式,也就是说可以支持在web服务器外的其他服务器上运行,通过tcp传输数据。

shell中的select用法


select也是循环的一种,它比较适合用在用户选择的情况下。
比如,我们有一个这样的需求,运行脚本后,让用户去选择数字,选择1,会运行w命令,选择2运行top命令,选择3运行free命令,选择4退出。脚本这样实现:

#!/bin/bashecho “Please chose a number, 1: run w, 2: run top, 3: run free, 4: quit”

echo

select command in w top free quit

do

case $command in

w)

w

;;

top)

top

;;

free)

free

;;

quit)

exit

;;

*)

echo “Please input a number:(1-4).”

;;

esac

done

执行结果如下:
sh select.sh
Please chose a number, 1: run w, 2: run top, 3: run free, 4: quit

1) w
2) top
3) free
4) quit
#? 1

16:06:58 up 109 days, 22:01,  1 user,  load average: 0.11, 0.05, 0.01

USER     TTY      FROM              LOGIN@   IDLE   JCPU   PCPU WHAT

root     pts/0    222.128.156.84   16:05    0.00s  0.00s  0.00s w

#? 3
total       used       free     shared    buffers     cached
Mem:       1020328     943736      76592          0      86840     263624
-/+ buffers/cache:     593272     427056
Swap:      2097144      44196    2052948
#?

我们发现,select会默认把序号对应的命令列出来,每次输入一个数字,则会执行相应的命令,命令执行完后并不会退出脚本。它还会继续让我们再次输如序号。序号前面的提示符,我们也是可以修改的,利用变量PS3即可,再次修改脚本如下:

#!/bin/bash

PS3=”Please select a number: ”

echo “Please chose a number, 1: run w, 2: run top, 3: run free, 4: quit”

echo

select command in w top free quit

do

case $command in

w)

w

;;

top)

top

;;

free)

free

;;

quit)

exit

;;

*)

echo “Please input a number:(1-4).”

esac

done

如果想要脚本每次输入一个序号后就自动退出,则需要再次更改脚本如下:

#!/bin/bash

PS3=”Please select a number: ”

echo “Please chose a number, 1: run w, 2: run top, 3: run free, 4: quit”

echo

select command in w top free quit

do

case $command in

w)

w;exit

;;

top)

top;exit

;;

free)

free;exit

;;

quit)

exit

;;

*)

echo “Please input a number:(1-4).”;exit

esac

done

tomcat单机多实例


需求是: 同一个tomcat服务下,可以访问多个域名。

先来看看tomcat配置文件server.xml的结构

<Server>

<Service name=”xxx”>

<Host  name=”aaa.com” appBase=”dir1″>

</Host>

</Service>

<Server>

说明:

Service下面可以定义监听的端口,包含了<Host></Host>,而<Host></Host>里面定义虚拟主机,即,定义站点的域名和站点的目录。

 

两种方案:

1 可以在<Service></Service>里面定义多个<Host></Host>,这样就定义了多个站点,但端口不能变。

2 可以在<Server></Server>里面定义多个<Service></Service>,<Service></Service>里再定义<Host></Host>,这样做的好处是,可以更改监听端口。

 

假设需求为:

同一个服务器上跑两个站点

www.aaa.com  监听端口是8080

www.bbb.com  监听端口是8081

 

配置文件内容为:

<GlobalNamingResources>
<!– Editable user database that can also be used by
UserDatabaseRealm to authenticate users
–>
<Resource name=”UserDatabase” auth=”Container”
type=”org.apache.catalina.UserDatabase”
description=”User database that can be updated and saved”
factory=”org.apache.catalina.users.MemoryUserDatabaseFactory”
pathname=”conf/tomcat-users.xml” />
</GlobalNamingResources>

<!– A “Service” is a collection of one or more “Connectors” that share
a single “Container” Note: A “Service” is not itself a “Container”,
so you may not define subcomponents such as “Valves” at this level.
Documentation at /docs/config/service.html
–>
<Service name=”Catalina”>

<Connector port=”8080″ protocol=”HTTP/1.1″
connectionTimeout=”20000″
redirectPort=”8443″ />
<Connector port=”8009″ protocol=”AJP/1.3″ redirectPort=”8443″ />

<Engine name=”Catalina” defaultHost=”localhost”>

<Realm className=”org.apache.catalina.realm.LockOutRealm”>
<Realm className=”org.apache.catalina.realm.UserDatabaseRealm”
resourceName=”UserDatabase”/>
</Realm>

<Host name=”www.aaa.com” appBase=”webapps”
unpackWARs=”true” autoDeploy=”true”>

<Valve className=”org.apache.catalina.valves.AccessLogValve” directory=”logs”
prefix=”aaa.com_access” suffix=”.log”
pattern=”%h %l %u %t &quot;%r&quot; %s %b” />

</Host>
</Engine>
</Service>
<Service name=”aming”>

<Connector port=”8081″ protocol=”HTTP/1.1″
connectionTimeout=”20000″
redirectPort=”8443″ />

<Engine name=”aming” defaultHost=”localhost”>

<Realm className=”org.apache.catalina.realm.LockOutRealm”>
<Realm className=”org.apache.catalina.realm.UserDatabaseRealm”
resourceName=”UserDatabase”/>
</Realm>

<Host name=”www.bbb.com” appBase=”/data/tomcat”
unpackWARs=”true” autoDeploy=”true”>

<Valve className=”org.apache.catalina.valves.AccessLogValve” directory=”logs”
prefix=”bbb.com_access” suffix=”.log”
pattern=”%h %l %u %t &quot;%r&quot; %s %b” />

</Host>
</Engine>
</Service>

</Server>